blob: 2f6d74a3dc4cda59e075a66bdadc96865dc84396 [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
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "api/rtp_parameters.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Danil Chapovalova39254d2019-03-26 14:10:16 +010019#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "call/call.h"
21#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "media/base/fake_media_engine.h"
23#include "media/base/fake_network_interface.h"
24#include "media/base/fake_rtp.h"
25#include "media/base/media_constants.h"
26#include "media/engine/fake_webrtc_call.h"
27#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/audio_device/include/mock_audio_device.h"
29#include "modules/audio_processing/include/mock_audio_processing.h"
30#include "pc/channel.h"
31#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010033#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "test/field_trial.h"
35#include "test/gtest.h"
36#include "test/mock_audio_decoder_factory.h"
37#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
Elad Alon157540a2019-02-08 23:37:52 +010039using ::testing::_;
40using ::testing::ContainerEq;
41using ::testing::Contains;
42using ::testing::Field;
43using ::testing::Return;
44using ::testing::ReturnPointee;
45using ::testing::SaveArg;
46using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000047
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010049using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020050
solenberg418b7d32017-06-13 00:38:27 -070051constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070052
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
54const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070055const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
57const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070058const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
59const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020060const cricket::AudioCodec kTelephoneEventCodec1(106,
61 "telephone-event",
62 8000,
63 0,
64 1);
65const cricket::AudioCodec kTelephoneEventCodec2(107,
66 "telephone-event",
67 32000,
68 0,
69 1);
solenberg2779bab2016-11-17 04:45:19 -080070
solenberg2100c0b2017-03-01 11:29:29 -080071const uint32_t kSsrc0 = 0;
72const uint32_t kSsrc1 = 1;
73const uint32_t kSsrcX = 0x99;
74const uint32_t kSsrcY = 0x17;
75const uint32_t kSsrcZ = 0x42;
76const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020077const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
solenberg971cab02016-06-14 10:02:41 -070079constexpr int kRtpHistoryMs = 5000;
80
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010081constexpr webrtc::GainControl::Mode kDefaultAgcMode =
82#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
83 webrtc::GainControl::kFixedDigital;
84#else
85 webrtc::GainControl::kAdaptiveAnalog;
86#endif
87
88constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
89 webrtc::NoiseSuppression::kHigh;
90
solenberg9a5f032222017-03-15 06:14:12 -070091void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
92 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010093
94 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010095 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010096 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010097 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070098#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020099 EXPECT_CALL(
100 *adm, SetPlayoutDevice(
101 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
102 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
103 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700104#else
105 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
106#endif // #if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
108 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
109 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100110#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200111 EXPECT_CALL(
112 *adm, SetRecordingDevice(
113 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
114 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
115 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100116#else
117 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
118#endif // #if defined(WEBRTC_WIN)
119 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
120 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
121 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700122 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
123 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
124 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100125
126 // Teardown.
127 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
128 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
129 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
130 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200131 EXPECT_CALL(*adm, Release())
132 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100133 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700134}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200135} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136
solenbergff976312016-03-30 23:28:51 -0700137// Tests that our stub library "works".
138TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
Danil Chapovalova39254d2019-03-26 14:10:16 +0100139 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
140 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -0700141 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700142 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700143 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
144 new rtc::RefCountedObject<
145 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700146 webrtc::AudioProcessing::Config apm_config;
147 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
148 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700149 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700150 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700151 {
ossuc54071d2016-08-17 02:45:41 -0700152 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +0100153 task_queue_factory.get(), &adm,
154 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100155 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700156 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700157 }
solenbergff976312016-03-30 23:28:51 -0700158}
159
deadbeef884f5852016-01-15 09:20:04 -0800160class FakeAudioSink : public webrtc::AudioSinkInterface {
161 public:
162 void OnData(const Data& audio) override {}
163};
164
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800165class FakeAudioSource : public cricket::AudioSource {
166 void SetSink(Sink* sink) override {}
167};
168
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169class WebRtcVoiceEngineTestFake : public testing::Test {
170 public:
stefanba4c0e42016-02-04 04:12:24 -0800171 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
172
173 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Danil Chapovalova39254d2019-03-26 14:10:16 +0100174 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
175 apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700176 StrictMock<webrtc::test::MockAudioProcessing>>()),
177 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700178 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100179 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700180 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800181 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700182 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800183 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700184 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
185 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700186 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700187 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800188 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100189 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800190 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100191 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
192 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800194 // Init does not overwrite default AGC config.
195 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
196 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
197 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800198 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
199 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700200 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800201 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700202 // factories. Those tests should probably be moved elsewhere.
203 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
204 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100205 engine_.reset(new cricket::WebRtcVoiceEngine(
Danil Chapovalova39254d2019-03-26 14:10:16 +0100206 task_queue_factory_.get(), &adm_, encoder_factory, decoder_factory,
207 nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700208 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200209 send_parameters_.codecs.push_back(kPcmuCodec);
210 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100211
solenberg76377c52017-02-21 00:54:31 -0800212 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200213 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800214 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100215 EXPECT_TRUE(IsTypingDetectionEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 }
solenberg8189b022016-06-14 12:13:00 -0700217
solenbergff976312016-03-30 23:28:51 -0700218 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700219 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100220 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
221 cricket::AudioOptions(),
222 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200223 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupRecvStream() {
227 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700228 return false;
229 }
solenberg2100c0b2017-03-01 11:29:29 -0800230 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700231 }
solenberg8189b022016-06-14 12:13:00 -0700232
solenbergff976312016-03-30 23:28:51 -0700233 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200234 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
235 }
236
237 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700238 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000239 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
Florent Castellidacec712018-05-24 16:24:21 +0200241 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800242 return false;
243 }
peaha9cc40b2017-06-29 08:32:09 -0700244 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800245 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 }
solenberg8189b022016-06-14 12:13:00 -0700247
248 bool AddRecvStream(uint32_t ssrc) {
249 EXPECT_TRUE(channel_);
250 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
251 }
252
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000253 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700254 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700255 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800256 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
257 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700258 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800259 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000260 }
solenberg8189b022016-06-14 12:13:00 -0700261
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700263 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700264 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000265 }
solenberg8189b022016-06-14 12:13:00 -0700266
Yves Gerey665174f2018-06-19 15:03:05 +0200267 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100269 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
270 const auto* send_stream = call_.GetAudioSendStream(ssrc);
271 EXPECT_TRUE(send_stream);
272 return *send_stream;
273 }
274
deadbeef884f5852016-01-15 09:20:04 -0800275 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
276 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
277 EXPECT_TRUE(recv_stream);
278 return *recv_stream;
279 }
280
solenberg3a941542015-11-16 07:34:50 -0800281 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800282 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800283 }
284
solenberg7add0582015-11-20 09:59:34 -0800285 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800286 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800287 }
288
solenberg059fb442016-10-26 05:12:24 -0700289 void SetSend(bool enable) {
290 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700291 if (enable) {
292 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
293 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
294 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700295 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700296 }
solenberg059fb442016-10-26 05:12:24 -0700297 channel_->SetSend(enable);
298 }
299
300 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700301 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700302 ASSERT_TRUE(channel_);
303 EXPECT_TRUE(channel_->SetSendParameters(params));
304 }
305
Yves Gerey665174f2018-06-19 15:03:05 +0200306 void SetAudioSend(uint32_t ssrc,
307 bool enable,
308 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700309 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700310 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700311 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700312 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700313 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700314 }
315 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700316 }
317
Yves Gerey665174f2018-06-19 15:03:05 +0200318 void TestInsertDtmf(uint32_t ssrc,
319 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800320 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700321 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700323 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200325 EXPECT_TRUE(
326 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000327 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700330 SetSendParameters(send_parameters_);
331 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800334 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700335 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000337
338 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700339 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800340 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200341 EXPECT_TRUE(
342 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000343 }
344
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800346 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100348 // Test send.
349 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800350 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100351 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800352 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800353 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800354 EXPECT_EQ(codec.id, telephone_event.payload_type);
355 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100356 EXPECT_EQ(2, telephone_event.event_code);
357 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358 }
359
Johannes Kron9190b822018-10-29 11:22:05 +0100360 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
361 // For a caller, the answer will be applied in set remote description
362 // where SetSendParameters() is called.
363 EXPECT_TRUE(SetupChannel());
364 EXPECT_TRUE(
365 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
366 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
367 SetSendParameters(send_parameters_);
368 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
369 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
370 }
371
372 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
373 // For a callee, the answer will be applied in set local description
374 // where SetExtmapAllowMixed() and AddSendStream() are called.
375 EXPECT_TRUE(SetupChannel());
376 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
377 EXPECT_TRUE(
378 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
379
380 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
381 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
382 }
383
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384 // Test that send bandwidth is set correctly.
385 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000386 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
387 // |expected_result| is the expected result from SetMaxSendBandwidth().
388 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700389 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
390 int max_bitrate,
391 bool expected_result,
392 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200393 cricket::AudioSendParameters parameters;
394 parameters.codecs.push_back(codec);
395 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700396 if (expected_result) {
397 SetSendParameters(parameters);
398 } else {
399 EXPECT_FALSE(channel_->SetSendParameters(parameters));
400 }
solenberg2100c0b2017-03-01 11:29:29 -0800401 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000402 }
403
skvlade0d46372016-04-07 22:59:22 -0700404 // Sets the per-stream maximum bitrate limit for the specified SSRC.
405 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700406 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700407 EXPECT_EQ(1UL, parameters.encodings.size());
408
Oskar Sundbom78807582017-11-16 11:09:55 +0100409 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800410 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700411 }
412
solenberg059fb442016-10-26 05:12:24 -0700413 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700414 cricket::AudioSendParameters send_parameters;
415 send_parameters.codecs.push_back(codec);
416 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700417 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700418 }
419
ossu20a4b3f2017-04-27 02:08:52 -0700420 void CheckSendCodecBitrate(int32_t ssrc,
421 const char expected_name[],
422 int expected_bitrate) {
423 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
424 EXPECT_EQ(expected_name, spec->format.name);
425 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700426 }
427
Danil Chapovalov00c71832018-06-15 15:58:38 +0200428 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700429 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700430 }
431
Danil Chapovalov00c71832018-06-15 15:58:38 +0200432 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
433 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700434 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
435 }
436
skvlade0d46372016-04-07 22:59:22 -0700437 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
438 int global_max,
439 int stream_max,
440 bool expected_result,
441 int expected_codec_bitrate) {
442 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800443 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700444
445 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700446 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800447 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700448
449 // Verify that reading back the parameters gives results
450 // consistent with the Set() result.
451 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800452 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700453 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
454 EXPECT_EQ(expected_result ? stream_max : -1,
455 resulting_parameters.encodings[0].max_bitrate_bps);
456
457 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800458 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700459 }
460
stefan13f1a0a2016-11-30 07:22:58 -0800461 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
462 int expected_min_bitrate_bps,
463 const char* start_bitrate_kbps,
464 int expected_start_bitrate_bps,
465 const char* max_bitrate_kbps,
466 int expected_max_bitrate_bps) {
467 EXPECT_TRUE(SetupSendStream());
468 auto& codecs = send_parameters_.codecs;
469 codecs.clear();
470 codecs.push_back(kOpusCodec);
471 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
472 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
473 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100474 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
475 SetSdpBitrateParameters(
476 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
477 expected_min_bitrate_bps),
478 Field(&BitrateConstraints::start_bitrate_bps,
479 expected_start_bitrate_bps),
480 Field(&BitrateConstraints::max_bitrate_bps,
481 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800482
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100483 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800484 }
485
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000486 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700487 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000488
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000491
492 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700493 send_parameters_.extensions.push_back(
494 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700495 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800496 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000497
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000498 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200499 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700500 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000502
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000503 // Ensure extension is set properly.
504 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700505 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700506 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800507 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
508 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
509 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000510
solenberg7add0582015-11-20 09:59:34 -0800511 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200512 EXPECT_TRUE(
513 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
515 call_.GetAudioSendStream(kSsrcY));
516 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
517 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
518 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000519
520 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200521 send_parameters_.codecs.push_back(kPcmuCodec);
522 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700523 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526 }
527
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000528 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700529 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000530
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000531 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800532 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000533
534 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700535 recv_parameters_.extensions.push_back(
536 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800537 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800538 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000539
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000540 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800541 recv_parameters_.extensions.clear();
542 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800543 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000544
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000545 // Ensure extension is set properly.
546 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700547 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800548 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800549 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
550 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
551 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000552
solenberg7add0582015-11-20 09:59:34 -0800553 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800554 EXPECT_TRUE(AddRecvStream(kSsrcY));
555 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
556 call_.GetAudioReceiveStream(kSsrcY));
557 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
558 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
559 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000560
561 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800562 recv_parameters_.extensions.clear();
563 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800564 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
565 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000566 }
567
solenberg85a04962015-10-27 03:35:21 -0700568 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
569 webrtc::AudioSendStream::Stats stats;
570 stats.local_ssrc = 12;
571 stats.bytes_sent = 345;
572 stats.packets_sent = 678;
573 stats.packets_lost = 9012;
574 stats.fraction_lost = 34.56f;
575 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100576 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700577 stats.ext_seqnum = 789;
578 stats.jitter_ms = 12;
579 stats.rtt_ms = 345;
580 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100581 stats.apm_statistics.delay_median_ms = 234;
582 stats.apm_statistics.delay_standard_deviation_ms = 567;
583 stats.apm_statistics.echo_return_loss = 890;
584 stats.apm_statistics.echo_return_loss_enhancement = 1234;
585 stats.apm_statistics.residual_echo_likelihood = 0.432f;
586 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100587 stats.ana_statistics.bitrate_action_counter = 321;
588 stats.ana_statistics.channel_action_counter = 432;
589 stats.ana_statistics.dtx_action_counter = 543;
590 stats.ana_statistics.fec_action_counter = 654;
591 stats.ana_statistics.frame_length_increase_counter = 765;
592 stats.ana_statistics.frame_length_decrease_counter = 876;
593 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700594 stats.typing_noise_detected = true;
595 return stats;
596 }
597 void SetAudioSendStreamStats() {
598 for (auto* s : call_.GetAudioSendStreams()) {
599 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200600 }
solenberg85a04962015-10-27 03:35:21 -0700601 }
solenberg566ef242015-11-06 15:34:49 -0800602 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
603 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700604 const auto stats = GetAudioSendStreamStats();
605 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
606 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
607 EXPECT_EQ(info.packets_sent, stats.packets_sent);
608 EXPECT_EQ(info.packets_lost, stats.packets_lost);
609 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
610 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800611 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700612 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
613 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
614 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
615 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100616 EXPECT_EQ(info.apm_statistics.delay_median_ms,
617 stats.apm_statistics.delay_median_ms);
618 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
619 stats.apm_statistics.delay_standard_deviation_ms);
620 EXPECT_EQ(info.apm_statistics.echo_return_loss,
621 stats.apm_statistics.echo_return_loss);
622 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
623 stats.apm_statistics.echo_return_loss_enhancement);
624 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
625 stats.apm_statistics.residual_echo_likelihood);
626 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
627 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700628 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
629 stats.ana_statistics.bitrate_action_counter);
630 EXPECT_EQ(info.ana_statistics.channel_action_counter,
631 stats.ana_statistics.channel_action_counter);
632 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
633 stats.ana_statistics.dtx_action_counter);
634 EXPECT_EQ(info.ana_statistics.fec_action_counter,
635 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700636 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
637 stats.ana_statistics.frame_length_increase_counter);
638 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
639 stats.ana_statistics.frame_length_decrease_counter);
640 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
641 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800642 EXPECT_EQ(info.typing_noise_detected,
643 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700644 }
645
646 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
647 webrtc::AudioReceiveStream::Stats stats;
648 stats.remote_ssrc = 123;
649 stats.bytes_rcvd = 456;
650 stats.packets_rcvd = 768;
651 stats.packets_lost = 101;
652 stats.fraction_lost = 23.45f;
653 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100654 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700655 stats.ext_seqnum = 678;
656 stats.jitter_ms = 901;
657 stats.jitter_buffer_ms = 234;
658 stats.jitter_buffer_preferred_ms = 567;
659 stats.delay_estimate_ms = 890;
660 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700661 stats.total_samples_received = 5678901;
662 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200663 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200664 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100665 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700666 stats.expand_rate = 5.67f;
667 stats.speech_expand_rate = 8.90f;
668 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200669 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700670 stats.accelerate_rate = 4.56f;
671 stats.preemptive_expand_rate = 7.89f;
672 stats.decoding_calls_to_silence_generator = 12;
673 stats.decoding_calls_to_neteq = 345;
674 stats.decoding_normal = 67890;
675 stats.decoding_plc = 1234;
676 stats.decoding_cng = 5678;
677 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700678 stats.decoding_muted_output = 3456;
679 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200680 return stats;
681 }
682 void SetAudioReceiveStreamStats() {
683 for (auto* s : call_.GetAudioReceiveStreams()) {
684 s->SetStats(GetAudioReceiveStreamStats());
685 }
686 }
687 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700688 const auto stats = GetAudioReceiveStreamStats();
689 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
690 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
692 stats.packets_rcvd);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
694 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700695 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
696 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800697 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
699 stats.ext_seqnum);
700 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
701 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
702 stats.jitter_buffer_ms);
703 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700704 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200705 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
706 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700707 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700708 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
709 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200710 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200711 EXPECT_EQ(info.jitter_buffer_delay_seconds,
712 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100713 EXPECT_EQ(info.jitter_buffer_emitted_count,
714 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700715 EXPECT_EQ(info.expand_rate, stats.expand_rate);
716 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
717 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200718 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700719 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
720 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200721 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700722 stats.decoding_calls_to_silence_generator);
723 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
724 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
725 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
726 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
727 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700728 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700729 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200730 }
hbos1acfbd22016-11-17 23:43:29 -0800731 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
732 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
733 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
734 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
735 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
736 codec.ToCodecParameters());
737 }
738 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
739 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
740 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
741 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
742 codec.ToCodecParameters());
743 }
744 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200745
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200746 bool IsEchoCancellationEnabled() {
747 return engine_->GetApmConfigForTest().echo_canceller.enabled;
748 }
749
peah8271d042016-11-22 07:24:52 -0800750 bool IsHighPassFilterEnabled() {
751 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
752 }
753
Sam Zackrissonba502232019-01-04 10:36:48 +0100754 bool IsTypingDetectionEnabled() {
755 return engine_->GetApmConfigForTest().voice_detection.enabled;
756 }
757
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758 protected:
Danil Chapovalova39254d2019-03-26 14:10:16 +0100759 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
solenbergbc37fc82016-04-04 09:54:44 -0700760 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700761 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800762 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800763 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200764 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700765 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700766 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200767 cricket::AudioSendParameters send_parameters_;
768 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800769 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700770 webrtc::AudioProcessing::Config apm_config_;
771
stefanba4c0e42016-02-04 04:12:24 -0800772 private:
773 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774};
775
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100777TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700778 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779}
780
solenberg31fec402016-05-06 02:13:12 -0700781// Test that we can add a send stream and that it has the correct defaults.
782TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
783 EXPECT_TRUE(SetupChannel());
784 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800785 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
786 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
787 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700788 EXPECT_EQ("", config.rtp.c_name);
789 EXPECT_EQ(0u, config.rtp.extensions.size());
790 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
791 config.send_transport);
792}
793
794// Test that we can add a receive stream and that it has the correct defaults.
795TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
796 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700798 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800799 GetRecvStreamConfig(kSsrcX);
800 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700801 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
802 EXPECT_FALSE(config.rtp.transport_cc);
803 EXPECT_EQ(0u, config.rtp.extensions.size());
804 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
805 config.rtcp_send_transport);
806 EXPECT_EQ("", config.sync_group);
807}
808
stefanba4c0e42016-02-04 04:12:24 -0800809TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700810 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800811 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100812 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800813 if (codec.name == "opus") {
814 EXPECT_TRUE(HasTransportCc(codec));
815 opus_found = true;
816 }
817 }
818 EXPECT_TRUE(opus_found);
819}
820
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821// Test that we set our inbound codecs properly, including changing PT.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700823 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 cricket::AudioRecvParameters parameters;
825 parameters.codecs.push_back(kIsacCodec);
826 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800827 parameters.codecs.push_back(kTelephoneEventCodec1);
828 parameters.codecs.push_back(kTelephoneEventCodec2);
829 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 parameters.codecs[2].id = 126;
831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800832 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700833 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
834 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
835 {{0, {"PCMU", 8000, 1}},
836 {106, {"ISAC", 16000, 1}},
837 {126, {"telephone-event", 8000, 1}},
838 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that we fail to set an unknown inbound codec.
842TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 cricket::AudioRecvParameters parameters;
845 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700846 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200847 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848}
849
850// Test that we fail if we have duplicate types in the inbound list.
851TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700852 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200853 cricket::AudioRecvParameters parameters;
854 parameters.codecs.push_back(kIsacCodec);
855 parameters.codecs.push_back(kCn16000Codec);
856 parameters.codecs[1].id = kIsacCodec.id;
857 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we can decode OPUS without stereo parameters.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
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(kPcmuCodec);
866 parameters.codecs.push_back(kOpusCodec);
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800868 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700869 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
870 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
871 {{0, {"PCMU", 8000, 1}},
872 {103, {"ISAC", 16000, 1}},
873 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874}
875
876// Test that we can decode OPUS with stereo = 0.
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
881 parameters.codecs.push_back(kPcmuCodec);
882 parameters.codecs.push_back(kOpusCodec);
883 parameters.codecs[2].params["stereo"] = "0";
884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800885 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700886 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
887 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
888 {{0, {"PCMU", 8000, 1}},
889 {103, {"ISAC", 16000, 1}},
890 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891}
892
893// Test that we can decode OPUS with stereo = 1.
894TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700895 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200896 cricket::AudioRecvParameters parameters;
897 parameters.codecs.push_back(kIsacCodec);
898 parameters.codecs.push_back(kPcmuCodec);
899 parameters.codecs.push_back(kOpusCodec);
900 parameters.codecs[2].params["stereo"] = "1";
901 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800902 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700903 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
904 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
905 {{0, {"PCMU", 8000, 1}},
906 {103, {"ISAC", 16000, 1}},
907 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908}
909
910// Test that changes to recv codecs are applied to all streams.
911TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700912 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 cricket::AudioRecvParameters parameters;
914 parameters.codecs.push_back(kIsacCodec);
915 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800916 parameters.codecs.push_back(kTelephoneEventCodec1);
917 parameters.codecs.push_back(kTelephoneEventCodec2);
918 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200919 parameters.codecs[2].id = 126;
920 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700921 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
922 EXPECT_TRUE(AddRecvStream(ssrc));
923 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
924 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
925 {{0, {"PCMU", 8000, 1}},
926 {106, {"ISAC", 16000, 1}},
927 {126, {"telephone-event", 8000, 1}},
928 {107, {"telephone-event", 32000, 1}}})));
929 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930}
931
932TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700933 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200934 cricket::AudioRecvParameters parameters;
935 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800936 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200937 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938
solenberg2100c0b2017-03-01 11:29:29 -0800939 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200940 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800941 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942}
943
944// Test that we can apply the same set of codecs again while playing.
945TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700946 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947 cricket::AudioRecvParameters parameters;
948 parameters.codecs.push_back(kIsacCodec);
949 parameters.codecs.push_back(kCn16000Codec);
950 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700951 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953
deadbeefcb383672017-04-26 16:28:42 -0700954 // Remapping a payload type to a different codec should fail.
955 parameters.codecs[0] = kOpusCodec;
956 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200957 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800958 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959}
960
961// Test that we can add a codec while playing.
962TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700963 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200964 cricket::AudioRecvParameters parameters;
965 parameters.codecs.push_back(kIsacCodec);
966 parameters.codecs.push_back(kCn16000Codec);
967 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700968 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200970 parameters.codecs.push_back(kOpusCodec);
971 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800972 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973}
974
deadbeefcb383672017-04-26 16:28:42 -0700975// Test that we accept adding the same codec with a different payload type.
976// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
977TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
978 EXPECT_TRUE(SetupRecvStream());
979 cricket::AudioRecvParameters parameters;
980 parameters.codecs.push_back(kIsacCodec);
981 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
982
983 ++parameters.codecs[0].id;
984 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
985}
986
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700988 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990 // Test that when autobw is enabled, bitrate is kept as the default
991 // value. autobw is enabled for the following tests because the target
992 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000993
994 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700995 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996
997 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700998 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
ossu20a4b3f2017-04-27 02:08:52 -07001000 // opus, default bitrate == 32000 in mono.
1001 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002}
1003
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001004TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001005 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001008 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1009 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001010 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001013 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1014 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1015 // Rates above the max (510000) should be capped.
1016 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017}
1018
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001019TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001020 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001021
1022 // Test that we can only set a maximum bitrate for a fixed-rate codec
1023 // if it's bigger than the fixed rate.
1024
1025 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001026 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1027 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1028 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1029 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1030 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1031 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1032 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001033}
1034
1035TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001036 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001037 const int kDesiredBitrate = 128000;
1038 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001039 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001040 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001041 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001042
Yves Gerey665174f2018-06-19 15:03:05 +02001043 EXPECT_TRUE(
1044 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001045
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001047}
1048
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001049// Test that bitrate cannot be set for CBR codecs.
1050// Bitrate is ignored if it is higher than the fixed bitrate.
1051// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001052TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001053 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054
1055 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001056 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001057 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001058
1059 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001060 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001061 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001062
1063 send_parameters_.max_bandwidth_bps = 128;
1064 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001066}
1067
skvlade0d46372016-04-07 22:59:22 -07001068// Test that the per-stream bitrate limit and the global
1069// bitrate limit both apply.
1070TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1071 EXPECT_TRUE(SetupSendStream());
1072
ossu20a4b3f2017-04-27 02:08:52 -07001073 // opus, default bitrate == 32000.
1074 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001075 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1076 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1077 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1078
1079 // CBR codecs allow both maximums to exceed the bitrate.
1080 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1081 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1082 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1083 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1084
1085 // CBR codecs don't allow per stream maximums to be too low.
1086 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1087 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1088}
1089
1090// Test that an attempt to set RtpParameters for a stream that does not exist
1091// fails.
1092TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1093 EXPECT_TRUE(SetupChannel());
1094 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001095 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001096 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001097
1098 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001099 EXPECT_FALSE(
1100 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001101}
1102
1103TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001104 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001105 // This test verifies that setting RtpParameters succeeds only if
1106 // the structure contains exactly one encoding.
1107 // TODO(skvlad): Update this test when we start supporting setting parameters
1108 // for each encoding individually.
1109
1110 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001111 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001112 // Two or more encodings should result in failure.
1113 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001114 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001115 // Zero encodings should also fail.
1116 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001117 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001118}
1119
1120// Changing the SSRC through RtpParameters is not allowed.
1121TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1122 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001123 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001124 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001125 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001126}
1127
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001128// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001129// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001130TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1131 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001132 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001133 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001134 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001135 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001136 ASSERT_EQ(1u, parameters.encodings.size());
1137 ASSERT_TRUE(parameters.encodings[0].active);
1138 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001139 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001140 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001141
1142 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001143 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001144 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001145 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001146 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001147 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001148}
1149
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150// Test that SetRtpSendParameters configures the correct encoding channel for
1151// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001152TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1153 SetupForMultiSendStream();
1154 // Create send streams.
1155 for (uint32_t ssrc : kSsrcs4) {
1156 EXPECT_TRUE(
1157 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1158 }
1159 // Configure one stream to be limited by the stream config, another to be
1160 // limited by the global max, and the third one with no per-stream limit
1161 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001162 SetGlobalMaxBitrate(kOpusCodec, 32000);
1163 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1164 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001165 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1166
ossu20a4b3f2017-04-27 02:08:52 -07001167 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1168 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1169 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001170
1171 // Remove the global cap; the streams should switch to their respective
1172 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001173 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001174 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1175 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1176 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001177}
1178
Tim Haloun648d28a2018-10-18 16:52:22 -07001179// RTCRtpEncodingParameters.network_priority must be one of a few values
1180// derived from the default priority, corresponding to very-low, low, medium,
1181// or high.
1182TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1183 EXPECT_TRUE(SetupSendStream());
1184 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1185 EXPECT_EQ(1UL, parameters.encodings.size());
1186 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1187 parameters.encodings[0].network_priority);
1188
1189 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1190 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1191 for (auto it : good_values) {
1192 parameters.encodings[0].network_priority = it;
1193 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1194 }
1195 for (auto it : bad_values) {
1196 parameters.encodings[0].network_priority = it;
1197 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1198 }
1199}
1200
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001201// Test that GetRtpSendParameters returns the currently configured codecs.
1202TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001203 EXPECT_TRUE(SetupSendStream());
1204 cricket::AudioSendParameters parameters;
1205 parameters.codecs.push_back(kIsacCodec);
1206 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001207 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001208
solenberg2100c0b2017-03-01 11:29:29 -08001209 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001210 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001211 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1212 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001213}
1214
Florent Castellidacec712018-05-24 16:24:21 +02001215// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1216TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1217 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1218 params.cname = "rtcpcname";
1219 EXPECT_TRUE(SetupSendStream(params));
1220
1221 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1222 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1223}
1224
Florent Castelliabe301f2018-06-12 18:33:49 +02001225TEST_F(WebRtcVoiceEngineTestFake,
1226 DetectRtpSendParameterHeaderExtensionsChange) {
1227 EXPECT_TRUE(SetupSendStream());
1228
1229 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1230 rtp_parameters.header_extensions.emplace_back();
1231
1232 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1233
1234 webrtc::RTCError result =
1235 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1236 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1237}
1238
deadbeefcb443432016-12-12 11:12:36 -08001239// Test that GetRtpSendParameters returns an SSRC.
1240TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1241 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001242 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001243 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001244 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001245}
1246
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001247// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001248TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001249 EXPECT_TRUE(SetupSendStream());
1250 cricket::AudioSendParameters parameters;
1251 parameters.codecs.push_back(kIsacCodec);
1252 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001253 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001254
solenberg2100c0b2017-03-01 11:29:29 -08001255 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001256
1257 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001258 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001259
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001260 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001261 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1262 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001263}
1264
minyuececec102017-03-27 13:04:25 -07001265// Test that max_bitrate_bps in send stream config gets updated correctly when
1266// SetRtpSendParameters is called.
1267TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1268 webrtc::test::ScopedFieldTrials override_field_trials(
1269 "WebRTC-Audio-SendSideBwe/Enabled/");
1270 EXPECT_TRUE(SetupSendStream());
1271 cricket::AudioSendParameters send_parameters;
1272 send_parameters.codecs.push_back(kOpusCodec);
1273 SetSendParameters(send_parameters);
1274
1275 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1276 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1277 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1278
1279 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001280 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001281 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001282
1283 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1284 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1285}
1286
Seth Hampson24722b32017-12-22 09:36:42 -08001287// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1288// a value <= 0, setting the parameters returns false.
1289TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1290 EXPECT_TRUE(SetupSendStream());
1291 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1292 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1293 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1294 rtp_parameters.encodings[0].bitrate_priority);
1295
1296 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001297 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001298 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001299 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001300}
1301
1302// Test that the bitrate_priority in the send stream config gets updated when
1303// SetRtpSendParameters is set for the VoiceMediaChannel.
1304TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1305 EXPECT_TRUE(SetupSendStream());
1306 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1307
1308 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1309 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1310 rtp_parameters.encodings[0].bitrate_priority);
1311 double new_bitrate_priority = 2.0;
1312 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001313 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001314
1315 // The priority should get set for both the audio channel's rtp parameters
1316 // and the audio send stream's audio config.
1317 EXPECT_EQ(
1318 new_bitrate_priority,
1319 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1320 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1321}
1322
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001323// Test that GetRtpReceiveParameters returns the currently configured codecs.
1324TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1325 EXPECT_TRUE(SetupRecvStream());
1326 cricket::AudioRecvParameters parameters;
1327 parameters.codecs.push_back(kIsacCodec);
1328 parameters.codecs.push_back(kPcmuCodec);
1329 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1330
1331 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001332 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001333 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1334 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1335 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1336}
1337
deadbeefcb443432016-12-12 11:12:36 -08001338// Test that GetRtpReceiveParameters returns an SSRC.
1339TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1340 EXPECT_TRUE(SetupRecvStream());
1341 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001342 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001343 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001344 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001345}
1346
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001347// Test that if we set/get parameters multiple times, we get the same results.
1348TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1349 EXPECT_TRUE(SetupRecvStream());
1350 cricket::AudioRecvParameters parameters;
1351 parameters.codecs.push_back(kIsacCodec);
1352 parameters.codecs.push_back(kPcmuCodec);
1353 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1354
1355 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001356 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001357
1358 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001359 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001360
1361 // ... And this shouldn't change the params returned by
1362 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001363 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1364 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001365}
1366
deadbeef3bc15102017-04-20 19:25:07 -07001367// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1368// aren't signaled. It should return an empty "RtpEncodingParameters" when
1369// configured to receive an unsignaled stream and no packets have been received
1370// yet, and start returning the SSRC once a packet has been received.
1371TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1372 ASSERT_TRUE(SetupChannel());
1373 // Call necessary methods to configure receiving a default stream as
1374 // soon as it arrives.
1375 cricket::AudioRecvParameters parameters;
1376 parameters.codecs.push_back(kIsacCodec);
1377 parameters.codecs.push_back(kPcmuCodec);
1378 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1379
1380 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1381 // stream. Should return nothing.
1382 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1383
1384 // Set a sink for an unsignaled stream.
1385 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1386 // Value of "0" means "unsignaled stream".
1387 channel_->SetRawAudioSink(0, std::move(fake_sink));
1388
1389 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1390 // in this method means "unsignaled stream".
1391 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1392 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1393 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1394
1395 // Receive PCMU packet (SSRC=1).
1396 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1397
1398 // The |ssrc| member should still be unset.
1399 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1400 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1401 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1402}
1403
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404// Test that we apply codecs properly.
1405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kIsacCodec);
1409 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001410 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001412 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001414 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1415 EXPECT_EQ(96, send_codec_spec.payload_type);
1416 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1417 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1418 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001419 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001420 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001421}
1422
ossu20a4b3f2017-04-27 02:08:52 -07001423// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1424// AudioSendStream.
1425TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001426 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001427 cricket::AudioSendParameters parameters;
1428 parameters.codecs.push_back(kIsacCodec);
1429 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001430 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 parameters.codecs[0].id = 96;
1432 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001433 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001436 // Calling SetSendCodec again with same codec which is already set.
1437 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001439 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001440}
1441
ossu20a4b3f2017-04-27 02:08:52 -07001442// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1443// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001444
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001445// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 cricket::AudioSendParameters parameters;
1449 parameters.codecs.push_back(kOpusCodec);
1450 parameters.codecs[0].bitrate = 0;
1451 parameters.codecs[0].clockrate = 50000;
1452 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453}
1454
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001455// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
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].channels = 0;
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, SetSendCodecOpusBad0Channels1Stereo) {
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 parameters.codecs[0].params["stereo"] = "1";
1473 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474}
1475
1476// Test that if channel is 1 for opus and there's no stereo, we fail.
1477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001478 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 cricket::AudioSendParameters parameters;
1480 parameters.codecs.push_back(kOpusCodec);
1481 parameters.codecs[0].bitrate = 0;
1482 parameters.codecs[0].channels = 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 stereo=0, we fail.
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
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 parameters.codecs[0].params["stereo"] = "0";
1494 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495}
1496
1497// Test that if channel is 1 for opus and stereo=1, we fail.
1498TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001499 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001500 cricket::AudioSendParameters parameters;
1501 parameters.codecs.push_back(kOpusCodec);
1502 parameters.codecs[0].bitrate = 0;
1503 parameters.codecs[0].channels = 1;
1504 parameters.codecs[0].params["stereo"] = "1";
1505 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001506}
1507
ossu20a4b3f2017-04-27 02:08:52 -07001508// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 cricket::AudioSendParameters parameters;
1512 parameters.codecs.push_back(kOpusCodec);
1513 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001514 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001515 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
ossu20a4b3f2017-04-27 02:08:52 -07001518// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
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;
1524 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001526 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
ossu20a4b3f2017-04-27 02:08:52 -07001529// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 cricket::AudioSendParameters parameters;
1533 parameters.codecs.push_back(kOpusCodec);
1534 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001535 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001536 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001537 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001538 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001539
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001542 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001543}
1544
ossu20a4b3f2017-04-27 02:08:52 -07001545// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001546TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001547 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 cricket::AudioSendParameters parameters;
1549 parameters.codecs.push_back(kOpusCodec);
1550 parameters.codecs[0].bitrate = 0;
1551 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001553 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554}
1555
ossu20a4b3f2017-04-27 02:08:52 -07001556// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001557TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001558 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001559 cricket::AudioSendParameters parameters;
1560 parameters.codecs.push_back(kOpusCodec);
1561 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001562 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001563 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001564 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001565 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001566
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001568 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001569 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001570}
1571
ossu20a4b3f2017-04-27 02:08:52 -07001572// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001574 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 cricket::AudioSendParameters parameters;
1576 parameters.codecs.push_back(kOpusCodec);
1577 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001579 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1580 EXPECT_EQ(111, spec.payload_type);
1581 EXPECT_EQ(96000, spec.target_bitrate_bps);
1582 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001583 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001584 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585}
1586
ossu20a4b3f2017-04-27 02:08:52 -07001587// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001589 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001590 cricket::AudioSendParameters parameters;
1591 parameters.codecs.push_back(kOpusCodec);
1592 parameters.codecs[0].bitrate = 30000;
1593 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001594 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001595 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596}
1597
ossu20a4b3f2017-04-27 02:08:52 -07001598// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001600 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001601 cricket::AudioSendParameters parameters;
1602 parameters.codecs.push_back(kOpusCodec);
1603 parameters.codecs[0].bitrate = 30000;
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 stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001609TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
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;
1614 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001616 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001617}
1618
stefan13f1a0a2016-11-30 07:22:58 -08001619TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1620 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1621 200000);
1622}
1623
1624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1625 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1626}
1627
1628TEST_F(WebRtcVoiceEngineTestFake,
1629 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1630 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1631}
1632
1633TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1634 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1635}
1636
Yves Gerey665174f2018-06-19 15:03:05 +02001637TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001638 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1639 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001640 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001641 // Setting max bitrate should keep previous min bitrate
1642 // Setting max bitrate should not reset start bitrate.
1643 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1644 SetSdpBitrateParameters(
1645 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1646 Field(&BitrateConstraints::start_bitrate_bps, -1),
1647 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001648 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001649}
1650
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001651// Test that we can enable NACK with opus as callee.
1652TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001653 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters parameters;
1655 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001656 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1657 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001658 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001660 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001661 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001662
Yves Gerey665174f2018-06-19 15:03:05 +02001663 EXPECT_TRUE(
1664 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001665}
1666
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667// Test that we can enable NACK on receive streams.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001670 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001673 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1674 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001676 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001677 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678}
1679
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680// Test that we can disable NACK on receive streams.
1681TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001682 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001684 cricket::AudioSendParameters parameters;
1685 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001686 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1687 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001688 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001689 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001691 parameters.codecs.clear();
1692 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001694 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001695}
1696
1697// Test that NACK is enabled on a new receive stream.
1698TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 cricket::AudioSendParameters parameters;
1701 parameters.codecs.push_back(kIsacCodec);
1702 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001703 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1704 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001706
solenberg2100c0b2017-03-01 11:29:29 -08001707 EXPECT_TRUE(AddRecvStream(kSsrcY));
1708 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1709 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1710 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711}
1712
stefanba4c0e42016-02-04 04:12:24 -08001713TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001714 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001715 cricket::AudioSendParameters send_parameters;
1716 send_parameters.codecs.push_back(kOpusCodec);
1717 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001718 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001719
1720 cricket::AudioRecvParameters recv_parameters;
1721 recv_parameters.codecs.push_back(kIsacCodec);
1722 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001723 EXPECT_TRUE(AddRecvStream(kSsrcX));
1724 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001725 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001726 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001727
ossudedfd282016-06-14 07:12:39 -07001728 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001730 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001731 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001732 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001733}
1734
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001735// Test that we can switch back and forth between Opus and ISAC with CN.
1736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001737 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001738
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters opus_parameters;
1740 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001741 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001742 {
ossu20a4b3f2017-04-27 02:08:52 -07001743 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1744 EXPECT_EQ(111, spec.payload_type);
1745 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001746 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001747
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 cricket::AudioSendParameters isac_parameters;
1749 isac_parameters.codecs.push_back(kIsacCodec);
1750 isac_parameters.codecs.push_back(kCn16000Codec);
1751 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001752 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001753 {
ossu20a4b3f2017-04-27 02:08:52 -07001754 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1755 EXPECT_EQ(103, spec.payload_type);
1756 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001757 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001760 {
ossu20a4b3f2017-04-27 02:08:52 -07001761 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1762 EXPECT_EQ(111, spec.payload_type);
1763 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001764 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765}
1766
1767// Test that we handle various ways of specifying bitrate.
1768TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001769 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001770 cricket::AudioSendParameters parameters;
1771 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001772 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001773 {
ossu20a4b3f2017-04-27 02:08:52 -07001774 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1775 EXPECT_EQ(103, spec.payload_type);
1776 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1777 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001778 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779
Yves Gerey665174f2018-06-19 15:03:05 +02001780 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001782 {
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(103, spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1786 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001787 }
Yves Gerey665174f2018-06-19 15:03:05 +02001788 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001790 {
ossu20a4b3f2017-04-27 02:08:52 -07001791 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1792 EXPECT_EQ(103, spec.payload_type);
1793 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1794 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001795 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796
Yves Gerey665174f2018-06-19 15:03:05 +02001797 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001799 {
ossu20a4b3f2017-04-27 02:08:52 -07001800 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1801 EXPECT_EQ(0, spec.payload_type);
1802 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1803 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001804 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805
Yves Gerey665174f2018-06-19 15:03:05 +02001806 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001808 {
ossu20a4b3f2017-04-27 02:08:52 -07001809 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1810 EXPECT_EQ(0, spec.payload_type);
1811 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1812 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001813 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 parameters.codecs[0] = kOpusCodec;
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(111, spec.payload_type);
1821 EXPECT_STREQ("opus", spec.format.name.c_str());
1822 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001823 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824}
1825
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001826// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001828 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 cricket::AudioSendParameters parameters;
1830 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001831}
1832
1833// Test that we can set send codecs even with telephone-event codec as the first
1834// one on the list.
1835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001838 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 parameters.codecs.push_back(kIsacCodec);
1840 parameters.codecs.push_back(kPcmuCodec);
1841 parameters.codecs[0].id = 98; // DTMF
1842 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001843 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001844 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1845 EXPECT_EQ(96, spec.payload_type);
1846 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001847 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001848 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001849}
1850
Harald Alvestranda1f66612018-02-21 11:24:23 +01001851// Test that CanInsertDtmf() is governed by the send flag
1852TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1853 EXPECT_TRUE(SetupSendStream());
1854 cricket::AudioSendParameters parameters;
1855 parameters.codecs.push_back(kTelephoneEventCodec1);
1856 parameters.codecs.push_back(kPcmuCodec);
1857 parameters.codecs[0].id = 98; // DTMF
1858 parameters.codecs[1].id = 96;
1859 SetSendParameters(parameters);
1860 EXPECT_FALSE(channel_->CanInsertDtmf());
1861 SetSend(true);
1862 EXPECT_TRUE(channel_->CanInsertDtmf());
1863 SetSend(false);
1864 EXPECT_FALSE(channel_->CanInsertDtmf());
1865}
1866
solenberg31642aa2016-03-14 08:00:37 -07001867// Test that payload type range is limited for telephone-event codec.
1868TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001870 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001871 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001872 parameters.codecs.push_back(kIsacCodec);
1873 parameters.codecs[0].id = 0; // DTMF
1874 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001875 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001876 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001877 EXPECT_TRUE(channel_->CanInsertDtmf());
1878 parameters.codecs[0].id = 128; // DTMF
1879 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1880 EXPECT_FALSE(channel_->CanInsertDtmf());
1881 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001882 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001883 EXPECT_TRUE(channel_->CanInsertDtmf());
1884 parameters.codecs[0].id = -1; // DTMF
1885 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1886 EXPECT_FALSE(channel_->CanInsertDtmf());
1887}
1888
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001889// Test that we can set send codecs even with CN codec as the first
1890// one on the list.
1891TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001892 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001893 cricket::AudioSendParameters parameters;
1894 parameters.codecs.push_back(kCn16000Codec);
1895 parameters.codecs.push_back(kIsacCodec);
1896 parameters.codecs.push_back(kPcmuCodec);
1897 parameters.codecs[0].id = 98; // wideband CN
1898 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001899 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001900 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1901 EXPECT_EQ(96, send_codec_spec.payload_type);
1902 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001903 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001904}
1905
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001906// Test that we set VAD and DTMF types correctly as caller.
1907TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001908 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 cricket::AudioSendParameters parameters;
1910 parameters.codecs.push_back(kIsacCodec);
1911 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001912 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001913 parameters.codecs.push_back(kCn16000Codec);
1914 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001915 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001916 parameters.codecs[0].id = 96;
1917 parameters.codecs[2].id = 97; // wideband CN
1918 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001919 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001920 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1921 EXPECT_EQ(96, send_codec_spec.payload_type);
1922 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001923 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001924 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001925 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001926 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001927}
1928
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001929// Test that we set VAD and DTMF types correctly as callee.
1930TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001931 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 cricket::AudioSendParameters parameters;
1933 parameters.codecs.push_back(kIsacCodec);
1934 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001935 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001936 parameters.codecs.push_back(kCn16000Codec);
1937 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001938 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001939 parameters.codecs[0].id = 96;
1940 parameters.codecs[2].id = 97; // wideband CN
1941 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001943 EXPECT_TRUE(
1944 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001945
ossu20a4b3f2017-04-27 02:08:52 -07001946 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1947 EXPECT_EQ(96, send_codec_spec.payload_type);
1948 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001949 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001950 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001951 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001952 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001953}
1954
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955// Test that we only apply VAD if we have a CN codec that matches the
1956// send codec clockrate.
1957TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001958 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001961 parameters.codecs.push_back(kIsacCodec);
1962 parameters.codecs.push_back(kCn16000Codec);
1963 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001964 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001965 {
ossu20a4b3f2017-04-27 02:08:52 -07001966 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1967 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001968 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001969 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001970 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001971 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001974 {
ossu20a4b3f2017-04-27 02:08:52 -07001975 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1976 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001977 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001978 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001979 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001982 {
ossu20a4b3f2017-04-27 02:08:52 -07001983 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1984 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001985 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001986 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001987 }
Brave Yao5225dd82015-03-26 07:39:19 +08001988 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001989 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001990 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001991 {
ossu20a4b3f2017-04-27 02:08:52 -07001992 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1993 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001994 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001995 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001996}
1997
1998// Test that we perform case-insensitive matching of codec names.
1999TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002000 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 cricket::AudioSendParameters parameters;
2002 parameters.codecs.push_back(kIsacCodec);
2003 parameters.codecs.push_back(kPcmuCodec);
2004 parameters.codecs.push_back(kCn16000Codec);
2005 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002006 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002007 parameters.codecs[0].name = "iSaC";
2008 parameters.codecs[0].id = 96;
2009 parameters.codecs[2].id = 97; // wideband CN
2010 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002011 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002012 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2013 EXPECT_EQ(96, send_codec_spec.payload_type);
2014 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002015 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002016 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002017 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002018 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002019}
2020
stefanba4c0e42016-02-04 04:12:24 -08002021class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2022 public:
2023 WebRtcVoiceEngineWithSendSideBweTest()
2024 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2025};
2026
2027TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2028 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002029 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2030 EXPECT_THAT(capabilities.header_extensions,
2031 Contains(testing::Field(
2032 "uri", &RtpExtension::uri,
2033 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002034}
2035
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002036// Test support for audio level header extension.
2037TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002038 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002039}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002040TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002041 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002042}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002043
solenbergd4adce42016-11-17 06:26:52 -08002044// Test support for transport sequence number header extension.
2045TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2046 TestSetSendRtpHeaderExtensions(
2047 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002048}
solenbergd4adce42016-11-17 06:26:52 -08002049TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2050 TestSetRecvRtpHeaderExtensions(
2051 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002052}
2053
solenberg1ac56142015-10-13 03:58:19 -07002054// Test that we can create a channel and start sending on it.
2055TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002056 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002057 SetSendParameters(send_parameters_);
2058 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002059 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002060 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002061 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002062}
2063
2064// Test that a channel will send if and only if it has a source and is enabled
2065// for sending.
2066TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002067 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002069 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002070 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2072 SetAudioSend(kSsrcX, true, &fake_source_);
2073 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2074 SetAudioSend(kSsrcX, true, nullptr);
2075 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002076}
2077
solenberg94218532016-06-16 10:53:22 -07002078// Test that a channel is muted/unmuted.
2079TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2080 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002081 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002082 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2083 SetAudioSend(kSsrcX, true, nullptr);
2084 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2085 SetAudioSend(kSsrcX, false, nullptr);
2086 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002087}
2088
solenberg6d6e7c52016-04-13 09:07:30 -07002089// Test that SetSendParameters() does not alter a stream's send state.
2090TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2091 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002092 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002093
2094 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002095 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002096 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002097
2098 // Changing RTP header extensions will recreate the AudioSendStream.
2099 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002100 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002101 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002102 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002103
2104 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002105 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002106 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002107
2108 // Changing RTP header extensions will recreate the AudioSendStream.
2109 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002110 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002112}
2113
solenberg1ac56142015-10-13 03:58:19 -07002114// Test that we can create a channel and start playing out on it.
2115TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002116 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002117 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002118 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002120 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002121 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122}
2123
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124// Test that we can add and remove send streams.
2125TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2126 SetupForMultiSendStream();
2127
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002129 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130
solenbergc96df772015-10-21 13:01:53 -07002131 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002132 EXPECT_TRUE(
2133 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002134 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002136 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137 }
tfarina5237aaf2015-11-10 23:44:30 -08002138 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139
solenbergc96df772015-10-21 13:01:53 -07002140 // Delete the send streams.
2141 for (uint32_t ssrc : kSsrcs4) {
2142 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002143 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002144 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 }
solenbergc96df772015-10-21 13:01:53 -07002146 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147}
2148
2149// Test SetSendCodecs correctly configure the codecs in all send streams.
2150TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2151 SetupForMultiSendStream();
2152
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002154 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002155 EXPECT_TRUE(
2156 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157 }
2158
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002159 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002160 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 parameters.codecs.push_back(kIsacCodec);
2162 parameters.codecs.push_back(kCn16000Codec);
2163 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002164 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165
2166 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002167 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002168 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2169 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002170 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2171 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002172 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002173 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002174 }
2175
minyue7a973442016-10-20 03:27:12 -07002176 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002177 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002178 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002179 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002180 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2181 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002182 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2183 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002184 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002185 }
2186}
2187
2188// Test we can SetSend on all send streams correctly.
2189TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2190 SetupForMultiSendStream();
2191
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002192 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002193 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002194 EXPECT_TRUE(
2195 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002196 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002197 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002198 }
2199
2200 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002201 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002202 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002204 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002205 }
2206
2207 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002208 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002209 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002210 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002211 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212 }
2213}
2214
2215// Test we can set the correct statistics on all send streams.
2216TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2217 SetupForMultiSendStream();
2218
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002219 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002220 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002221 EXPECT_TRUE(
2222 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002223 }
solenberg85a04962015-10-27 03:35:21 -07002224
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002225 // Create a receive stream to check that none of the send streams end up in
2226 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002228
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002229 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002230 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002231 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002232 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002233
solenberg85a04962015-10-27 03:35:21 -07002234 // Check stats for the added streams.
2235 {
2236 cricket::VoiceMediaInfo info;
2237 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002238
solenberg85a04962015-10-27 03:35:21 -07002239 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002240 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002241 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002242 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002243 }
hbos1acfbd22016-11-17 23:43:29 -08002244 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002245
2246 // We have added one receive stream. We should see empty stats.
2247 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002248 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002249 }
solenberg1ac56142015-10-13 03:58:19 -07002250
solenberg2100c0b2017-03-01 11:29:29 -08002251 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002252 {
2253 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002254 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002255 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002256 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002257 EXPECT_EQ(0u, info.receivers.size());
2258 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002259
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002260 // Deliver a new packet - a default receive stream should be created and we
2261 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002262 {
2263 cricket::VoiceMediaInfo info;
2264 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2265 SetAudioReceiveStreamStats();
2266 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002267 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002268 EXPECT_EQ(1u, info.receivers.size());
2269 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002270 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002271 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002272}
2273
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002274// Test that we can add and remove receive streams, and do proper send/playout.
2275// We can receive on multiple streams while sending one stream.
2276TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002277 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002278
solenberg1ac56142015-10-13 03:58:19 -07002279 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002280 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002281 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002282
solenberg1ac56142015-10-13 03:58:19 -07002283 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002284 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002285 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
solenberg1ac56142015-10-13 03:58:19 -07002288 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290
2291 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2293 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2294 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295
2296 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002297 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002298 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002299
2300 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002301 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002302 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2303 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304
aleloi84ef6152016-08-04 05:28:21 -07002305 // Restart playout and make sure recv streams are played out.
2306 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002307 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2308 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002309
aleloi84ef6152016-08-04 05:28:21 -07002310 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002311 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2312 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002313}
2314
wu@webrtc.org97077a32013-10-25 21:18:33 +00002315TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002316 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002317 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2318 .Times(1)
2319 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002320 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2321 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002322 send_parameters_.options.tx_agc_target_dbov = 3;
2323 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2324 send_parameters_.options.tx_agc_limiter = true;
2325 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002326 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2327 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2328 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002329 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002330}
2331
minyue6b825df2016-10-31 04:08:32 -07002332TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2333 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002334 send_parameters_.options.audio_network_adaptor = true;
2335 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002336 SetSendParameters(send_parameters_);
2337 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002338 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002339}
2340
2341TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2342 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002343 send_parameters_.options.audio_network_adaptor = true;
2344 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002345 SetSendParameters(send_parameters_);
2346 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002347 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002348 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002349 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002350 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002351 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002352}
2353
2354TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2355 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002356 send_parameters_.options.audio_network_adaptor = true;
2357 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002358 SetSendParameters(send_parameters_);
2359 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002360 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002361 const int initial_num = call_.GetNumCreatedSendStreams();
2362 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002363 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002364 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2365 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002366 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002367 // AudioSendStream not expected to be recreated.
2368 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
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
michaelt6672b262017-01-11 10:17:59 -08002373class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2374 : public WebRtcVoiceEngineTestFake {
2375 public:
2376 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2377 : WebRtcVoiceEngineTestFake(
2378 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2379 "Enabled/") {}
2380};
2381
2382TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2383 EXPECT_TRUE(SetupSendStream());
2384 cricket::AudioSendParameters parameters;
2385 parameters.codecs.push_back(kOpusCodec);
2386 SetSendParameters(parameters);
2387 const int initial_num = call_.GetNumCreatedSendStreams();
2388 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2389
2390 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2391 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002392 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2393 constexpr int kMinOverheadBps =
2394 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002395
2396 constexpr int kOpusMinBitrateBps = 6000;
2397 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002398 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002399 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002400 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002401 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002402
Oskar Sundbom78807582017-11-16 11:09:55 +01002403 parameters.options.audio_network_adaptor = true;
2404 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002405 SetSendParameters(parameters);
2406
ossu11bfc532017-02-16 05:37:06 -08002407 constexpr int kMinOverheadWithAnaBps =
2408 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002409
2410 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002411 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002412
minyuececec102017-03-27 13:04:25 -07002413 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002414 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002415}
2416
minyuececec102017-03-27 13:04:25 -07002417// This test is similar to
2418// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2419// additional field trial.
2420TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2421 SetRtpSendParameterUpdatesMaxBitrate) {
2422 EXPECT_TRUE(SetupSendStream());
2423 cricket::AudioSendParameters send_parameters;
2424 send_parameters.codecs.push_back(kOpusCodec);
2425 SetSendParameters(send_parameters);
2426
2427 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2428 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2429 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2430
2431 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002432 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002433 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002434
2435 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2436#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2437 constexpr int kMinOverhead = 3333;
2438#else
2439 constexpr int kMinOverhead = 6666;
2440#endif
2441 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2442}
2443
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002445// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002448 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449}
2450
2451TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2452 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002453 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002454 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002455 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002456 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002457 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002458 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002459 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460
solenberg85a04962015-10-27 03:35:21 -07002461 // Check stats for the added streams.
2462 {
2463 cricket::VoiceMediaInfo info;
2464 EXPECT_EQ(true, channel_->GetStats(&info));
2465
2466 // We have added one send stream. We should see the stats we've set.
2467 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002468 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002469 // We have added one receive stream. We should see empty stats.
2470 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002471 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002472 }
solenberg1ac56142015-10-13 03:58:19 -07002473
solenberg566ef242015-11-06 15:34:49 -08002474 // Start sending - this affects some reported stats.
2475 {
2476 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002477 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002478 EXPECT_EQ(true, channel_->GetStats(&info));
2479 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002480 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002481 }
2482
solenberg2100c0b2017-03-01 11:29:29 -08002483 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002484 {
2485 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002486 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002487 EXPECT_EQ(true, channel_->GetStats(&info));
2488 EXPECT_EQ(1u, info.senders.size());
2489 EXPECT_EQ(0u, info.receivers.size());
2490 }
solenberg1ac56142015-10-13 03:58:19 -07002491
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002492 // Deliver a new packet - a default receive stream should be created and we
2493 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002494 {
2495 cricket::VoiceMediaInfo info;
2496 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2497 SetAudioReceiveStreamStats();
2498 EXPECT_EQ(true, channel_->GetStats(&info));
2499 EXPECT_EQ(1u, info.senders.size());
2500 EXPECT_EQ(1u, info.receivers.size());
2501 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002502 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002503 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504}
2505
2506// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002507// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002509 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002510 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2511 EXPECT_TRUE(AddRecvStream(kSsrcY));
2512 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513}
2514
2515// Test that the local SSRC is the same on sending and receiving channels if the
2516// receive channel is created before the send channel.
2517TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002518 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002519 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002520 EXPECT_TRUE(
2521 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002522 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2523 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524}
2525
2526// Test that we can properly receive packets.
2527TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002528 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002529 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002530 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002531
Yves Gerey665174f2018-06-19 15:03:05 +02002532 EXPECT_TRUE(
2533 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534}
2535
2536// Test that we can properly receive packets on multiple streams.
2537TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002538 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002539 const uint32_t ssrc1 = 1;
2540 const uint32_t ssrc2 = 2;
2541 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002542 EXPECT_TRUE(AddRecvStream(ssrc1));
2543 EXPECT_TRUE(AddRecvStream(ssrc2));
2544 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002545 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002546 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002547 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002549 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 }
mflodman3d7db262016-04-29 00:57:13 -07002551
2552 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2553 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2554 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2555
2556 EXPECT_EQ(s1.received_packets(), 0);
2557 EXPECT_EQ(s2.received_packets(), 0);
2558 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002559
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_EQ(s1.received_packets(), 0);
2562 EXPECT_EQ(s2.received_packets(), 0);
2563 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002564
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002566 EXPECT_EQ(s1.received_packets(), 1);
2567 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2568 EXPECT_EQ(s2.received_packets(), 0);
2569 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002570
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002571 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_EQ(s1.received_packets(), 1);
2573 EXPECT_EQ(s2.received_packets(), 1);
2574 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2575 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002576
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002577 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002578 EXPECT_EQ(s1.received_packets(), 1);
2579 EXPECT_EQ(s2.received_packets(), 1);
2580 EXPECT_EQ(s3.received_packets(), 1);
2581 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002582
mflodman3d7db262016-04-29 00:57:13 -07002583 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2584 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2585 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002586}
2587
solenberg2100c0b2017-03-01 11:29:29 -08002588// Test that receiving on an unsignaled stream works (a stream is created).
2589TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002590 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002591 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002592
solenberg7e63ef02015-11-20 00:19:43 -08002593 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002594
Mirko Bonadeif859e552018-05-30 15:31:29 +02002595 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002596 EXPECT_TRUE(
2597 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002598}
2599
Seth Hampson5897a6e2018-04-03 11:16:33 -07002600// Tests that when we add a stream without SSRCs, but contains a stream_id
2601// that it is stored and its stream id is later used when the first packet
2602// arrives to properly create a receive stream with a sync label.
2603TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2604 const char kSyncLabel[] = "sync_label";
2605 EXPECT_TRUE(SetupChannel());
2606 cricket::StreamParams unsignaled_stream;
2607 unsignaled_stream.set_stream_ids({kSyncLabel});
2608 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2609 // The stream shouldn't have been created at this point because it doesn't
2610 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002611 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002612
2613 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2614
Mirko Bonadeif859e552018-05-30 15:31:29 +02002615 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002616 EXPECT_TRUE(
2617 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2618 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2619
2620 // Removing the unsignaled stream clears the cached parameters. If a new
2621 // default unsignaled receive stream is created it will not have a sync group.
2622 channel_->RemoveRecvStream(0);
2623 channel_->RemoveRecvStream(kSsrc1);
2624
2625 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2626
Mirko Bonadeif859e552018-05-30 15:31:29 +02002627 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002628 EXPECT_TRUE(
2629 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2630 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2631}
2632
solenberg2100c0b2017-03-01 11:29:29 -08002633// Test that receiving N unsignaled stream works (streams will be created), and
2634// that packets are forwarded to them all.
2635TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002636 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002637 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002638 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2639
solenberg2100c0b2017-03-01 11:29:29 -08002640 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002641 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002642 rtc::SetBE32(&packet[8], ssrc);
2643 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002644
solenberg2100c0b2017-03-01 11:29:29 -08002645 // Verify we have one new stream for each loop iteration.
2646 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002647 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2648 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002649 }
mflodman3d7db262016-04-29 00:57:13 -07002650
solenberg2100c0b2017-03-01 11:29:29 -08002651 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002652 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002653 rtc::SetBE32(&packet[8], ssrc);
2654 DeliverPacket(packet, sizeof(packet));
2655
solenbergebb349d2017-03-13 05:46:15 -07002656 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002657 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2658 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2659 }
2660
2661 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2662 constexpr uint32_t kAnotherSsrc = 667;
2663 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002664 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002665
2666 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002667 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002668 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002669 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002670 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2671 EXPECT_EQ(2, streams[i]->received_packets());
2672 }
2673 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2674 EXPECT_EQ(1, streams[i]->received_packets());
2675 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002676 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002677}
2678
solenberg2100c0b2017-03-01 11:29:29 -08002679// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002680// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002681TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002682 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002683 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002684 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2685
2686 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002687 const uint32_t signaled_ssrc = 1;
2688 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002689 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002690 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002691 EXPECT_TRUE(
2692 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002693 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002694
2695 // Note that the first unknown SSRC cannot be 0, because we only support
2696 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002697 const uint32_t unsignaled_ssrc = 7011;
2698 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002699 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002700 EXPECT_TRUE(
2701 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002702 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002703
2704 DeliverPacket(packet, sizeof(packet));
2705 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2706
2707 rtc::SetBE32(&packet[8], signaled_ssrc);
2708 DeliverPacket(packet, sizeof(packet));
2709 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002710 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002711}
2712
solenberg4904fb62017-02-17 12:01:14 -08002713// Two tests to verify that adding a receive stream with the same SSRC as a
2714// previously added unsignaled stream will only recreate underlying stream
2715// objects if the stream parameters have changed.
2716TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2717 EXPECT_TRUE(SetupChannel());
2718
2719 // Spawn unsignaled stream with SSRC=1.
2720 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002721 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002722 EXPECT_TRUE(
2723 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002724
2725 // Verify that the underlying stream object in Call is not recreated when a
2726 // stream with SSRC=1 is added.
2727 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002728 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002729 int audio_receive_stream_id = streams.front()->id();
2730 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002731 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002732 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2733}
2734
2735TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2736 EXPECT_TRUE(SetupChannel());
2737
2738 // Spawn unsignaled stream with SSRC=1.
2739 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002740 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002741 EXPECT_TRUE(
2742 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002743
2744 // Verify that the underlying stream object in Call *is* recreated when a
2745 // stream with SSRC=1 is added, and which has changed stream parameters.
2746 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002747 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002748 int audio_receive_stream_id = streams.front()->id();
2749 cricket::StreamParams stream_params;
2750 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002751 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002752 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002753 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002754 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2755}
2756
solenberg1ac56142015-10-13 03:58:19 -07002757// Test that AddRecvStream creates new stream.
2758TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761}
2762
2763// Test that after adding a recv stream, we do not decode more codecs than
2764// those previously passed into SetRecvCodecs.
2765TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002767 cricket::AudioRecvParameters parameters;
2768 parameters.codecs.push_back(kIsacCodec);
2769 parameters.codecs.push_back(kPcmuCodec);
2770 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002771 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002772 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2773 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2774 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775}
2776
2777// Test that we properly clean up any streams that were added, even if
2778// not explicitly removed.
2779TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002780 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002781 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002782 EXPECT_TRUE(AddRecvStream(1));
2783 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002784
Mirko Bonadeif859e552018-05-30 15:31:29 +02002785 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2786 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002787 delete channel_;
2788 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002789 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2790 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
wu@webrtc.org78187522013-10-07 23:32:02 +00002793TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002794 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002795 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002796}
2797
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002798TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002799 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002800 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002801 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002802}
2803
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002804// Test the InsertDtmf on default send stream as caller.
2805TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002806 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807}
2808
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002809// Test the InsertDtmf on default send stream as callee
2810TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002811 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002812}
2813
2814// Test the InsertDtmf on specified send stream as caller.
2815TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002816 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002817}
2818
2819// Test the InsertDtmf on specified send stream as callee.
2820TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002821 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822}
2823
Johannes Kron9190b822018-10-29 11:22:05 +01002824// Test propagation of extmap allow mixed setting.
2825TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2826 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2827}
2828TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2829 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2830}
2831TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2832 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2833}
2834TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2835 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2836}
2837
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002838TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002840 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002841 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2842 .Times(9)
2843 .WillRepeatedly(Return(false));
2844 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2845 .Times(4)
2846 .WillRepeatedly(Return(false));
2847 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2848 .Times(2)
2849 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002850
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002851 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002852 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
solenberg246b8172015-12-08 09:50:23 -08002854 // Nothing set in AudioOptions, so everything should be as default.
2855 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002856 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002857 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002858 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002859 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002860 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002861 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002862
Sam Zackrissonba502232019-01-04 10:36:48 +01002863 // Turn typing detection off.
2864 send_parameters_.options.typing_detection = false;
2865 SetSendParameters(send_parameters_);
2866 EXPECT_FALSE(IsTypingDetectionEnabled());
2867
2868 // Leave typing detection unchanged, but non-default.
2869 send_parameters_.options.typing_detection = absl::nullopt;
2870 SetSendParameters(send_parameters_);
2871 EXPECT_FALSE(IsTypingDetectionEnabled());
2872
2873 // Turn typing detection on.
2874 send_parameters_.options.typing_detection = true;
2875 SetSendParameters(send_parameters_);
2876 EXPECT_TRUE(IsTypingDetectionEnabled());
2877
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002879 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002880 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002881 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
2883 // Turn echo cancellation back on, with settings, and make sure
2884 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002885 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002886 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002887 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002888
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002889 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2890 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002891 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002892 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002893 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002894
2895 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002896 send_parameters_.options.delay_agnostic_aec = false;
2897 send_parameters_.options.extended_filter_aec = false;
2898 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002899 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002900 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002901
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002902 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002903 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002904 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002905 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002906
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002908 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002909 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002910 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002911 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002912 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913
2914 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002917 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002918 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002919 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002920
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002921 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002922 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002923 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002924 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002925 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002926 send_parameters_.options.noise_suppression = false;
2927 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002928 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002929 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002930 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002931 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932
solenberg1ac56142015-10-13 03:58:19 -07002933 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002934 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002936 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002937 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002938 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002939 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002940}
2941
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002943 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002944 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2945 .Times(8)
2946 .WillRepeatedly(Return(false));
2947 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2948 .Times(8)
2949 .WillRepeatedly(Return(false));
2950 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2951 .Times(8)
2952 .WillRepeatedly(Return(false));
2953 EXPECT_CALL(adm_, RecordingIsInitialized())
2954 .Times(2)
2955 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002956 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2957 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002958 webrtc::AudioProcessing::Config apm_config;
2959 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002960 .WillRepeatedly(ReturnPointee(&apm_config));
2961 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002962 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002963 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002964
kwiberg686a8ef2016-02-26 03:00:35 -08002965 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002966 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2967 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2968 cricket::AudioOptions(),
2969 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002970 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002971 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2972 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2973 cricket::AudioOptions(),
2974 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975
2976 // Have to add a stream to make SetSend work.
2977 cricket::StreamParams stream1;
2978 stream1.ssrcs.push_back(1);
2979 channel1->AddSendStream(stream1);
2980 cricket::StreamParams stream2;
2981 stream2.ssrcs.push_back(2);
2982 channel2->AddSendStream(stream2);
2983
2984 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002985 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002986 parameters_options_all.options.echo_cancellation = true;
2987 parameters_options_all.options.auto_gain_control = true;
2988 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002989 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002990 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002991 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002992 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002993 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002994 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002995 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002996 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002997 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002998 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
3000 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003002 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003003 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003004 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003005 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003006 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003007 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003008 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003009 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003010 expected_options.echo_cancellation = true;
3011 expected_options.auto_gain_control = true;
3012 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003013 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014
3015 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003016 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003017 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003018 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003019 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003020 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003021 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003022 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003023 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003024 expected_options.echo_cancellation = true;
3025 expected_options.auto_gain_control = false;
3026 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003027 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003029 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003030 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003031 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003032 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003033 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003034 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003036 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003037 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003038 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003039 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003040 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003041 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003042
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003043 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003044 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003045 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003046 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003047 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003048 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003049
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003051 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3052 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003053 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3054 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003055 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003056 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003057 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003058 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003059 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003060 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003061 expected_options.echo_cancellation = true;
3062 expected_options.auto_gain_control = false;
3063 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003064 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003065}
3066
wu@webrtc.orgde305012013-10-31 15:40:38 +00003067// This test verifies DSCP settings are properly applied on voice media channel.
3068TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003069 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003070 cricket::FakeNetworkInterface network_interface;
3071 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003072 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003073 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003074
peahb1c9d1d2017-07-25 15:45:24 -07003075 webrtc::AudioProcessing::Config apm_config;
3076 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003077 .WillRepeatedly(ReturnPointee(&apm_config));
3078 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003079 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003080 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003081
Sebastian Jansson84848f22018-11-16 10:40:36 +01003082 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3083 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3084 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003085 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003086 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3087 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3088
3089 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003090 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3091 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3092 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003093 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003094 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3095
3096 // Create a send stream to configure
3097 EXPECT_TRUE(
3098 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3099 parameters = channel->GetRtpSendParameters(kSsrcZ);
3100 ASSERT_FALSE(parameters.encodings.empty());
3101
3102 // Various priorities map to various dscp values.
3103 parameters.encodings[0].network_priority = 4.0;
3104 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003105 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003106 parameters.encodings[0].network_priority = 0.5;
3107 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3108 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3109
3110 // A bad priority does not change the dscp value.
3111 parameters.encodings[0].network_priority = 0.0;
3112 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3113 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003114
Tim Haloun6ca98362018-09-17 17:06:08 -07003115 // Packets should also self-identify their dscp in PacketOptions.
3116 const uint8_t kData[10] = {0};
3117 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003118 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003119
nisse51542be2016-02-12 02:27:06 -08003120 // Verify that setting the option to false resets the
3121 // DiffServCodePoint.
3122 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003123 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3124 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3125 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003126 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003127 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3128 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3129
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003130 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003131}
3132
solenberg4bac9c52015-10-09 02:32:53 -07003133TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003134 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003135 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003136 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003137 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003138 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003139 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3140 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3141 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003142}
3143
solenberg2100c0b2017-03-01 11:29:29 -08003144TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003145 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003146
3147 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003148 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003149 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3150
3151 // Should remember the volume "2" which will be set on new unsignaled streams,
3152 // and also set the gain to 2 on existing unsignaled streams.
3153 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3154 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3155
3156 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3157 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3158 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3159 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3160 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3161 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3162
3163 // Setting gain with SSRC=0 should affect all unsignaled streams.
3164 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003165 if (kMaxUnsignaledRecvStreams > 1) {
3166 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3167 }
solenberg2100c0b2017-03-01 11:29:29 -08003168 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3169
3170 // Setting gain on an individual stream affects only that.
3171 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003172 if (kMaxUnsignaledRecvStreams > 1) {
3173 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3174 }
solenberg2100c0b2017-03-01 11:29:29 -08003175 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003176}
3177
Ruslan Burakov7ea46052019-02-16 02:07:05 +01003178TEST_F(WebRtcVoiceEngineTestFake, BaseMinimumPlayoutDelayMs) {
3179 EXPECT_TRUE(SetupChannel());
3180 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 200));
3181 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3182
3183 cricket::StreamParams stream;
3184 stream.ssrcs.push_back(kSsrcY);
3185 EXPECT_TRUE(channel_->AddRecvStream(stream));
3186 EXPECT_EQ(0, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3187 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcY, 300));
3188 EXPECT_EQ(300, GetRecvStream(kSsrcY).base_mininum_playout_delay_ms());
3189}
3190
3191TEST_F(WebRtcVoiceEngineTestFake,
3192 BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
3193 // Here base minimum delay is abbreviated to delay in comments for shortness.
3194 EXPECT_TRUE(SetupChannel());
3195
3196 // Spawn an unsignaled stream by sending a packet - delay should be 0.
3197 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3198 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3199 // Check that it doesn't provide default values for unknown ssrc.
3200 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3201
3202 // Check that default value for unsignaled streams is 0.
3203 EXPECT_EQ(0, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3204
3205 // Should remember the delay 100 which will be set on new unsignaled streams,
3206 // and also set the delay to 100 on existing unsignaled streams.
3207 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 100));
3208 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3209 // Check that it doesn't provide default values for unknown ssrc.
3210 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3211
3212 // Spawn an unsignaled stream by sending a packet - delay should be 100.
3213 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3214 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3215 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3216 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3217 EXPECT_EQ(100, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3218
3219 // Setting delay with SSRC=0 should affect all unsignaled streams.
3220 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc0, 300));
3221 if (kMaxUnsignaledRecvStreams > 1) {
3222 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3223 }
3224 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3225
3226 // Setting delay on an individual stream affects only that.
3227 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrcX, 400));
3228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc1).value_or(-1));
3230 }
3231 EXPECT_EQ(400, channel_->GetBaseMinimumPlayoutDelayMs(kSsrcX).value_or(-1));
3232 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(kSsrc0).value_or(-1));
3233 // Check that it doesn't provide default values for unknown ssrc.
3234 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrcY).has_value());
3235}
3236
Seth Hampson845e8782018-03-02 11:34:10 -08003237TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003238 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003239 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003240
solenbergff976312016-03-30 23:28:51 -07003241 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003242 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003243 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003244 // Creating two channels to make sure that sync label is set properly for both
3245 // the default voice channel and following ones.
3246 EXPECT_TRUE(channel_->AddRecvStream(sp));
3247 sp.ssrcs[0] += 1;
3248 EXPECT_TRUE(channel_->AddRecvStream(sp));
3249
Mirko Bonadeif859e552018-05-30 15:31:29 +02003250 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003251 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003252 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003253 << "SyncGroup should be set based on stream id";
3254 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003255 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003256 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003257}
3258
solenberg3a941542015-11-16 07:34:50 -08003259// TODO(solenberg): Remove, once recv streams are configured through Call.
3260// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003261TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003262 // Test that setting the header extensions results in the expected state
3263 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003264 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003265 ssrcs.push_back(223);
3266 ssrcs.push_back(224);
3267
solenbergff976312016-03-30 23:28:51 -07003268 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003269 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003270 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003271 EXPECT_TRUE(
3272 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 }
3274
Mirko Bonadeif859e552018-05-30 15:31:29 +02003275 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003276 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003277 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003278 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003279 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003280 }
3281
3282 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003283 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003284 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003285 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003286 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003287 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003288 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003289 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003290 EXPECT_NE(nullptr, s);
3291 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003292 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3293 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003294 for (const auto& s_ext : s_exts) {
3295 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003296 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003297 }
3298 }
3299 }
3300 }
3301
3302 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003303 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003304 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003305 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003306 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003307 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003308 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003309}
3310
3311TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3312 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003313 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003314 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003315 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003316 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3317 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003319 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003320
solenbergff976312016-03-30 23:28:51 -07003321 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003322 cricket::WebRtcVoiceMediaChannel* media_channel =
3323 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003324 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003325 EXPECT_TRUE(media_channel->AddRecvStream(
3326 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3327
Mirko Bonadeif859e552018-05-30 15:31:29 +02003328 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003329 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003330 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003331 EXPECT_EQ(0, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003332 channel_->OnPacketReceived(kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003333 EXPECT_EQ(1, s->received_packets());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07003334 channel_->OnRtcpReceived(kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003335 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003336}
Minyue2013aec2015-05-13 14:14:42 +02003337
solenberg0a617e22015-10-20 15:49:38 -07003338// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003339// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003340TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003341 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003342 EXPECT_TRUE(AddRecvStream(kSsrcY));
3343 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003344 EXPECT_TRUE(
3345 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3347 EXPECT_TRUE(AddRecvStream(kSsrcW));
3348 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003349}
3350
solenberg7602aab2016-11-14 11:30:07 -08003351TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3352 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003353 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003354 EXPECT_TRUE(
3355 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003356 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3357 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3358 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003359 EXPECT_TRUE(
3360 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003361 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3362 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003363}
stefan658910c2015-09-03 05:48:32 -07003364
deadbeef884f5852016-01-15 09:20:04 -08003365TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003366 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003367 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3368 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003369
3370 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003371 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3372 EXPECT_TRUE(AddRecvStream(kSsrcX));
3373 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003374
3375 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003376 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3377 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003378
3379 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003380 channel_->SetRawAudioSink(kSsrcX, nullptr);
3381 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003382}
3383
solenberg2100c0b2017-03-01 11:29:29 -08003384TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003385 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003386 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3387 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003388 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3389 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003390
3391 // Should be able to set a default sink even when no stream exists.
3392 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3393
solenberg2100c0b2017-03-01 11:29:29 -08003394 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3395 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003396 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003397 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003398
3399 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003400 channel_->SetRawAudioSink(kSsrc0, nullptr);
3401 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003402
3403 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003404 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3405 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003406
3407 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003408 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003409 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003410 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3411
3412 // Spawn another unsignaled stream - it should be assigned the default sink
3413 // and the previous unsignaled stream should lose it.
3414 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3415 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3416 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3417 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003418 if (kMaxUnsignaledRecvStreams > 1) {
3419 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3420 }
solenberg2100c0b2017-03-01 11:29:29 -08003421 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3422
3423 // Reset the default sink - the second unsignaled stream should lose it.
3424 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003425 if (kMaxUnsignaledRecvStreams > 1) {
3426 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3427 }
solenberg2100c0b2017-03-01 11:29:29 -08003428 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3429
3430 // Try setting the default sink while two streams exists.
3431 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003432 if (kMaxUnsignaledRecvStreams > 1) {
3433 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3434 }
solenberg2100c0b2017-03-01 11:29:29 -08003435 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3436
3437 // Try setting the sink for the first unsignaled stream using its known SSRC.
3438 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003439 if (kMaxUnsignaledRecvStreams > 1) {
3440 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3441 }
solenberg2100c0b2017-03-01 11:29:29 -08003442 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003443 if (kMaxUnsignaledRecvStreams > 1) {
3444 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3445 }
deadbeef884f5852016-01-15 09:20:04 -08003446}
3447
skvlad7a43d252016-03-22 15:32:27 -07003448// Test that, just like the video channel, the voice channel communicates the
3449// network state to the call.
3450TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003451 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003452
3453 EXPECT_EQ(webrtc::kNetworkUp,
3454 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3455 EXPECT_EQ(webrtc::kNetworkUp,
3456 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3457
3458 channel_->OnReadyToSend(false);
3459 EXPECT_EQ(webrtc::kNetworkDown,
3460 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3461 EXPECT_EQ(webrtc::kNetworkUp,
3462 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3463
3464 channel_->OnReadyToSend(true);
3465 EXPECT_EQ(webrtc::kNetworkUp,
3466 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3467 EXPECT_EQ(webrtc::kNetworkUp,
3468 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3469}
3470
aleloi18e0b672016-10-04 02:45:47 -07003471// Test that playout is still started after changing parameters
3472TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3473 SetupRecvStream();
3474 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003475 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003476
3477 // Changing RTP header extensions will recreate the AudioReceiveStream.
3478 cricket::AudioRecvParameters parameters;
3479 parameters.extensions.push_back(
3480 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3481 channel_->SetRecvParameters(parameters);
3482
solenberg2100c0b2017-03-01 11:29:29 -08003483 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003484}
3485
Zhi Huangfa266ef2017-12-13 10:27:46 -08003486// Tests when GetSources is called with non-existing ssrc, it will return an
3487// empty list of RtpSource without crashing.
3488TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3489 // Setup an recv stream with |kSsrcX|.
3490 SetupRecvStream();
3491 cricket::WebRtcVoiceMediaChannel* media_channel =
3492 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3493 // Call GetSources with |kSsrcY| which doesn't exist.
3494 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3495 EXPECT_EQ(0u, sources.size());
3496}
3497
stefan658910c2015-09-03 05:48:32 -07003498// Tests that the library initializes and shuts down properly.
3499TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003500 // If the VoiceEngine wants to gather available codecs early, that's fine but
3501 // we never want it to create a decoder at this stage.
Danil Chapovalova39254d2019-03-26 14:10:16 +01003502 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3503 webrtc::CreateDefaultTaskQueueFactory();
henrika919dc2e2017-10-12 14:24:55 +02003504 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003505 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003506 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003507 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +01003508 task_queue_factory.get(), &adm,
3509 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003510 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003511 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003512 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003513 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003514 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003515 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3516 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3517 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003518 EXPECT_TRUE(channel != nullptr);
3519 delete channel;
solenbergff976312016-03-30 23:28:51 -07003520}
stefan658910c2015-09-03 05:48:32 -07003521
solenbergff976312016-03-30 23:28:51 -07003522// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003523TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
Danil Chapovalova39254d2019-03-26 14:10:16 +01003524 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3525 webrtc::CreateDefaultTaskQueueFactory();
solenbergbc37fc82016-04-04 09:54:44 -07003526 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003527 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003528 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003529 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003530 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003531 {
peaha9cc40b2017-06-29 08:32:09 -07003532 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003533 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003534 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +01003535 task_queue_factory.get(), &adm,
3536 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003537 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003538 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003539 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003540 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003541 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003542 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3543 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3544 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003545 EXPECT_TRUE(channel != nullptr);
3546 delete channel;
3547 }
stefan658910c2015-09-03 05:48:32 -07003548}
3549
ossu20a4b3f2017-04-27 02:08:52 -07003550// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3551TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
Danil Chapovalova39254d2019-03-26 14:10:16 +01003552 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3553 webrtc::CreateDefaultTaskQueueFactory();
ossuc54071d2016-08-17 02:45:41 -07003554 // TODO(ossu): Why are the payload types of codecs with non-static payload
3555 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003556 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003557 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003558 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003559 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +01003560 task_queue_factory.get(), &adm,
3561 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003562 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003563 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003564 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003565 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003566 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003567 (clockrate == 0 || codec.clockrate == clockrate);
3568 };
3569 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003570 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003571 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003572 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003573 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003574 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003575 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003576 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003577 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003578 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003579 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003580 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003581 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3582 // Remove these checks once both send and receive side assigns payload
3583 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003584 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003585 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003586 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003587 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003588 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003589 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003590 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003591 EXPECT_EQ(111, codec.id);
3592 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3593 EXPECT_EQ("10", codec.params.find("minptime")->second);
3594 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3595 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003596 }
3597 }
stefan658910c2015-09-03 05:48:32 -07003598}
3599
3600// Tests that VoE supports at least 32 channels
3601TEST(WebRtcVoiceEngineTest, Has32Channels) {
Danil Chapovalova39254d2019-03-26 14:10:16 +01003602 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3603 webrtc::CreateDefaultTaskQueueFactory();
henrika919dc2e2017-10-12 14:24:55 +02003604 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003605 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003606 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003607 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +01003608 task_queue_factory.get(), &adm,
3609 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003610 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003611 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003612 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003613 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003614 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003615
3616 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003617 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003618 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003619 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3620 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3621 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003622 if (!channel)
3623 break;
stefan658910c2015-09-03 05:48:32 -07003624 channels[num_channels++] = channel;
3625 }
3626
Mirko Bonadeif859e552018-05-30 15:31:29 +02003627 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003628 EXPECT_EQ(expected, num_channels);
3629
3630 while (num_channels > 0) {
3631 delete channels[--num_channels];
3632 }
stefan658910c2015-09-03 05:48:32 -07003633}
3634
3635// Test that we set our preferred codecs properly.
3636TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
Danil Chapovalova39254d2019-03-26 14:10:16 +01003637 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3638 webrtc::CreateDefaultTaskQueueFactory();
ossu29b1a8d2016-06-13 07:34:51 -07003639 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3640 // - Check that our builtin codecs are usable by Channel.
3641 // - The codecs provided by the engine is usable by Channel.
3642 // It does not check that the codecs in the RecvParameters are actually
3643 // what we sent in - though it's probably reasonable to expect so, if
3644 // SetRecvParameters returns true.
3645 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003646 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003647 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003648 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003649 cricket::WebRtcVoiceEngine engine(
Danil Chapovalova39254d2019-03-26 14:10:16 +01003650 task_queue_factory.get(), &adm,
3651 webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003652 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003653 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003654 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003655 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003656 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003657 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003658 cricket::AudioOptions(),
3659 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003660 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003661 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003662 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003663}
ossu9def8002017-02-09 05:14:32 -08003664
3665TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3666 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003667 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3668 {48000, 2, 16000, 10000, 20000}};
3669 spec1.info.allow_comfort_noise = false;
3670 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003671 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003672 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3673 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003674 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003675 specs.push_back(webrtc::AudioCodecSpec{
3676 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3677 {16000, 1, 13300}});
3678 specs.push_back(
3679 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3680 specs.push_back(
3681 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003682
Danil Chapovalova39254d2019-03-26 14:10:16 +01003683 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory =
3684 webrtc::CreateDefaultTaskQueueFactory();
ossueb1fde42017-05-02 06:46:30 -07003685 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3686 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3687 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003688 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003689 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003690 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003691 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003692
peaha9cc40b2017-06-29 08:32:09 -07003693 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003694 webrtc::AudioProcessingBuilder().Create();
Danil Chapovalova39254d2019-03-26 14:10:16 +01003695 cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), &adm,
3696 unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003697 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003698 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003699 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003700 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003701
3702 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3703 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003704 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3705 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3706 if (codecs.size() > index)
3707 return codecs[index];
3708 return missing_codec;
3709 };
ossu9def8002017-02-09 05:14:32 -08003710
3711 // Ensure the general codecs are generated first and in order.
3712 for (size_t i = 0; i != specs.size(); ++i) {
3713 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3714 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3715 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3716 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3717 }
3718
3719 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003720 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003721 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3722 for (size_t i = 0; i != codecs.size(); ++i) {
3723 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003724 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003725 codec.clockrate == format.clockrate_hz &&
3726 codec.channels == format.num_channels) {
3727 return rtc::checked_cast<int>(i);
3728 }
3729 }
3730 return -1;
3731 };
ossu9def8002017-02-09 05:14:32 -08003732
3733 // Ensure all supplementary codecs are generated last. Their internal ordering
3734 // is not important.
3735 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3736 const int num_specs = static_cast<int>(specs.size());
3737 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3738 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3739 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3740 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3741 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3742 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3743 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3744}