blob: 8930b9940f9d6c9df9efad15a0322dae64beae57 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "call/call.h"
20#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/base/fake_media_engine.h"
22#include "media/base/fake_network_interface.h"
23#include "media/base/fake_rtp.h"
24#include "media/base/media_constants.h"
25#include "media/engine/fake_webrtc_call.h"
26#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_device/include/mock_audio_device.h"
28#include "modules/audio_processing/include/mock_audio_processing.h"
29#include "pc/channel.h"
30#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010032#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "test/field_trial.h"
34#include "test/gtest.h"
35#include "test/mock_audio_decoder_factory.h"
36#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
Elad Alon157540a2019-02-08 23:37:52 +010038using ::testing::_;
39using ::testing::ContainerEq;
40using ::testing::Contains;
41using ::testing::Field;
42using ::testing::Return;
43using ::testing::ReturnPointee;
44using ::testing::SaveArg;
45using ::testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000046
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020047namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010048using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020049
solenberg418b7d32017-06-13 00:38:27 -070050constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070051
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
53const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070054const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
56const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070057const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
58const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020059const cricket::AudioCodec kTelephoneEventCodec1(106,
60 "telephone-event",
61 8000,
62 0,
63 1);
64const cricket::AudioCodec kTelephoneEventCodec2(107,
65 "telephone-event",
66 32000,
67 0,
68 1);
solenberg2779bab2016-11-17 04:45:19 -080069
solenberg2100c0b2017-03-01 11:29:29 -080070const uint32_t kSsrc0 = 0;
71const uint32_t kSsrc1 = 1;
72const uint32_t kSsrcX = 0x99;
73const uint32_t kSsrcY = 0x17;
74const uint32_t kSsrcZ = 0x42;
75const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020076const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077
solenberg971cab02016-06-14 10:02:41 -070078constexpr int kRtpHistoryMs = 5000;
79
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010080constexpr webrtc::AudioProcessing::Config::GainController1::Mode
81 kDefaultAgcMode =
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010082#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010083 webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010084#else
Sam Zackrissonf0d1c032019-03-27 13:28:08 +010085 webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010086#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) {
solenbergbc37fc82016-04-04 09:54:44 -0700139 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700140 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700141 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
142 new rtc::RefCountedObject<
143 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700144 webrtc::AudioProcessing::Config apm_config;
145 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
146 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700147 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700148 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700149 {
ossuc54071d2016-08-17 02:45:41 -0700150 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +0000151 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100152 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700153 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700154 }
solenbergff976312016-03-30 23:28:51 -0700155}
156
deadbeef884f5852016-01-15 09:20:04 -0800157class FakeAudioSink : public webrtc::AudioSinkInterface {
158 public:
159 void OnData(const Data& audio) override {}
160};
161
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800162class FakeAudioSource : public cricket::AudioSource {
163 void SetSink(Sink* sink) override {}
164};
165
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166class WebRtcVoiceEngineTestFake : public testing::Test {
167 public:
stefanba4c0e42016-02-04 04:12:24 -0800168 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
169
170 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
Amit Hilbuche27ccf92019-03-26 17:36:53 +0000171 : apm_(new rtc::RefCountedObject<
peaha9cc40b2017-06-29 08:32:09 -0700172 StrictMock<webrtc::test::MockAudioProcessing>>()),
peaha9cc40b2017-06-29 08:32:09 -0700173 apm_ns_(*apm_->noise_suppression()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100174 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700175 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800176 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700177 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800178 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700179 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
180 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700182 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800183 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100184 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800185 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700186 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800187 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700188 // factories. Those tests should probably be moved elsewhere.
189 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
190 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100191 engine_.reset(new cricket::WebRtcVoiceEngine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +0000192 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700193 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200194 send_parameters_.codecs.push_back(kPcmuCodec);
195 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100196
solenberg76377c52017-02-21 00:54:31 -0800197 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200198 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800199 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100200 EXPECT_TRUE(IsTypingDetectionEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100201 VerifyGainControlEnabledCorrectly();
202 VerifyGainControlDefaultSettings();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 }
solenberg8189b022016-06-14 12:13:00 -0700204
solenbergff976312016-03-30 23:28:51 -0700205 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700206 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100207 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
208 cricket::AudioOptions(),
209 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200210 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000211 }
solenberg8189b022016-06-14 12:13:00 -0700212
solenbergff976312016-03-30 23:28:51 -0700213 bool SetupRecvStream() {
214 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700215 return false;
216 }
solenberg2100c0b2017-03-01 11:29:29 -0800217 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700218 }
solenberg8189b022016-06-14 12:13:00 -0700219
solenbergff976312016-03-30 23:28:51 -0700220 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200221 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
222 }
223
224 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700225 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000226 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 }
Florent Castellidacec712018-05-24 16:24:21 +0200228 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800229 return false;
230 }
peaha9cc40b2017-06-29 08:32:09 -0700231 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800232 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
solenberg8189b022016-06-14 12:13:00 -0700234
235 bool AddRecvStream(uint32_t ssrc) {
236 EXPECT_TRUE(channel_);
237 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
238 }
239
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000240 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700241 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700242 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800243 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
244 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700245 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800246 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 }
solenberg8189b022016-06-14 12:13:00 -0700248
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700250 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -0700251 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 }
solenberg8189b022016-06-14 12:13:00 -0700253
Yves Gerey665174f2018-06-19 15:03:05 +0200254 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100256 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
257 const auto* send_stream = call_.GetAudioSendStream(ssrc);
258 EXPECT_TRUE(send_stream);
259 return *send_stream;
260 }
261
deadbeef884f5852016-01-15 09:20:04 -0800262 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
263 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
264 EXPECT_TRUE(recv_stream);
265 return *recv_stream;
266 }
267
solenberg3a941542015-11-16 07:34:50 -0800268 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800269 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800270 }
271
solenberg7add0582015-11-20 09:59:34 -0800272 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800273 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800274 }
275
solenberg059fb442016-10-26 05:12:24 -0700276 void SetSend(bool enable) {
277 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700278 if (enable) {
279 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
280 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
281 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700282 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700283 }
solenberg059fb442016-10-26 05:12:24 -0700284 channel_->SetSend(enable);
285 }
286
287 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700289 ASSERT_TRUE(channel_);
290 EXPECT_TRUE(channel_->SetSendParameters(params));
291 }
292
Yves Gerey665174f2018-06-19 15:03:05 +0200293 void SetAudioSend(uint32_t ssrc,
294 bool enable,
295 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700296 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700297 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700298 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700299 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700300 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700301 }
302 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700303 }
304
Yves Gerey665174f2018-06-19 15:03:05 +0200305 void TestInsertDtmf(uint32_t ssrc,
306 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800307 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700308 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000309 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700310 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000311 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200312 EXPECT_TRUE(
313 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700317 SetSendParameters(send_parameters_);
318 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800320 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800321 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700322 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324
325 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700326 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800327 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200328 EXPECT_TRUE(
329 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330 }
331
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100335 // Test send.
336 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800337 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100338 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800340 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800341 EXPECT_EQ(codec.id, telephone_event.payload_type);
342 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100343 EXPECT_EQ(2, telephone_event.event_code);
344 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 }
346
Johannes Kron9190b822018-10-29 11:22:05 +0100347 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
348 // For a caller, the answer will be applied in set remote description
349 // where SetSendParameters() is called.
350 EXPECT_TRUE(SetupChannel());
351 EXPECT_TRUE(
352 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
353 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
354 SetSendParameters(send_parameters_);
355 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
356 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
357 }
358
359 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
360 // For a callee, the answer will be applied in set local description
361 // where SetExtmapAllowMixed() and AddSendStream() are called.
362 EXPECT_TRUE(SetupChannel());
363 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
364 EXPECT_TRUE(
365 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
366
367 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
368 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
369 }
370
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371 // Test that send bandwidth is set correctly.
372 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000373 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
374 // |expected_result| is the expected result from SetMaxSendBandwidth().
375 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700376 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
377 int max_bitrate,
378 bool expected_result,
379 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200380 cricket::AudioSendParameters parameters;
381 parameters.codecs.push_back(codec);
382 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700383 if (expected_result) {
384 SetSendParameters(parameters);
385 } else {
386 EXPECT_FALSE(channel_->SetSendParameters(parameters));
387 }
solenberg2100c0b2017-03-01 11:29:29 -0800388 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 }
390
skvlade0d46372016-04-07 22:59:22 -0700391 // Sets the per-stream maximum bitrate limit for the specified SSRC.
392 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700393 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700394 EXPECT_EQ(1UL, parameters.encodings.size());
395
Oskar Sundbom78807582017-11-16 11:09:55 +0100396 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800397 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700398 }
399
solenberg059fb442016-10-26 05:12:24 -0700400 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700401 cricket::AudioSendParameters send_parameters;
402 send_parameters.codecs.push_back(codec);
403 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700404 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700405 }
406
ossu20a4b3f2017-04-27 02:08:52 -0700407 void CheckSendCodecBitrate(int32_t ssrc,
408 const char expected_name[],
409 int expected_bitrate) {
410 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
411 EXPECT_EQ(expected_name, spec->format.name);
412 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700413 }
414
Danil Chapovalov00c71832018-06-15 15:58:38 +0200415 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700416 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700417 }
418
Danil Chapovalov00c71832018-06-15 15:58:38 +0200419 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
420 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700421 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
422 }
423
skvlade0d46372016-04-07 22:59:22 -0700424 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
425 int global_max,
426 int stream_max,
427 bool expected_result,
428 int expected_codec_bitrate) {
429 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800430 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700431
432 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700433 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800434 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700435
436 // Verify that reading back the parameters gives results
437 // consistent with the Set() result.
438 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800439 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700440 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
441 EXPECT_EQ(expected_result ? stream_max : -1,
442 resulting_parameters.encodings[0].max_bitrate_bps);
443
444 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800445 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700446 }
447
stefan13f1a0a2016-11-30 07:22:58 -0800448 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
449 int expected_min_bitrate_bps,
450 const char* start_bitrate_kbps,
451 int expected_start_bitrate_bps,
452 const char* max_bitrate_kbps,
453 int expected_max_bitrate_bps) {
454 EXPECT_TRUE(SetupSendStream());
455 auto& codecs = send_parameters_.codecs;
456 codecs.clear();
457 codecs.push_back(kOpusCodec);
458 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
459 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
460 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100461 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
462 SetSdpBitrateParameters(
463 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
464 expected_min_bitrate_bps),
465 Field(&BitrateConstraints::start_bitrate_bps,
466 expected_start_bitrate_bps),
467 Field(&BitrateConstraints::max_bitrate_bps,
468 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800469
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100470 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800471 }
472
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700474 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000475
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000476 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800477 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000478
479 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700480 send_parameters_.extensions.push_back(
481 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700482 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000484
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200486 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700487 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800488 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000489
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000490 // Ensure extension is set properly.
491 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700492 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
495 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
496 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000497
solenberg7add0582015-11-20 09:59:34 -0800498 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200499 EXPECT_TRUE(
500 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
502 call_.GetAudioSendStream(kSsrcY));
503 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
504 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
505 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000506
507 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200508 send_parameters_.codecs.push_back(kPcmuCodec);
509 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700510 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
512 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513 }
514
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000515 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700516 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000517
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000518 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800519 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000520
521 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700522 recv_parameters_.extensions.push_back(
523 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000527 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800528 recv_parameters_.extensions.clear();
529 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800530 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000531
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000532 // Ensure extension is set properly.
533 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700534 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800535 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800536 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
537 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
538 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000539
solenberg7add0582015-11-20 09:59:34 -0800540 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800541 EXPECT_TRUE(AddRecvStream(kSsrcY));
542 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
543 call_.GetAudioReceiveStream(kSsrcY));
544 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
545 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
546 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000547
548 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800549 recv_parameters_.extensions.clear();
550 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800551 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
552 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000553 }
554
solenberg85a04962015-10-27 03:35:21 -0700555 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
556 webrtc::AudioSendStream::Stats stats;
557 stats.local_ssrc = 12;
558 stats.bytes_sent = 345;
559 stats.packets_sent = 678;
560 stats.packets_lost = 9012;
561 stats.fraction_lost = 34.56f;
562 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100563 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700564 stats.ext_seqnum = 789;
565 stats.jitter_ms = 12;
566 stats.rtt_ms = 345;
567 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100568 stats.apm_statistics.delay_median_ms = 234;
569 stats.apm_statistics.delay_standard_deviation_ms = 567;
570 stats.apm_statistics.echo_return_loss = 890;
571 stats.apm_statistics.echo_return_loss_enhancement = 1234;
572 stats.apm_statistics.residual_echo_likelihood = 0.432f;
573 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100574 stats.ana_statistics.bitrate_action_counter = 321;
575 stats.ana_statistics.channel_action_counter = 432;
576 stats.ana_statistics.dtx_action_counter = 543;
577 stats.ana_statistics.fec_action_counter = 654;
578 stats.ana_statistics.frame_length_increase_counter = 765;
579 stats.ana_statistics.frame_length_decrease_counter = 876;
580 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700581 stats.typing_noise_detected = true;
582 return stats;
583 }
584 void SetAudioSendStreamStats() {
585 for (auto* s : call_.GetAudioSendStreams()) {
586 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200587 }
solenberg85a04962015-10-27 03:35:21 -0700588 }
solenberg566ef242015-11-06 15:34:49 -0800589 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
590 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700591 const auto stats = GetAudioSendStreamStats();
592 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
593 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
594 EXPECT_EQ(info.packets_sent, stats.packets_sent);
595 EXPECT_EQ(info.packets_lost, stats.packets_lost);
596 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
597 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800598 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700599 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
600 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
601 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
602 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100603 EXPECT_EQ(info.apm_statistics.delay_median_ms,
604 stats.apm_statistics.delay_median_ms);
605 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
606 stats.apm_statistics.delay_standard_deviation_ms);
607 EXPECT_EQ(info.apm_statistics.echo_return_loss,
608 stats.apm_statistics.echo_return_loss);
609 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
610 stats.apm_statistics.echo_return_loss_enhancement);
611 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
612 stats.apm_statistics.residual_echo_likelihood);
613 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
614 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700615 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
616 stats.ana_statistics.bitrate_action_counter);
617 EXPECT_EQ(info.ana_statistics.channel_action_counter,
618 stats.ana_statistics.channel_action_counter);
619 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
620 stats.ana_statistics.dtx_action_counter);
621 EXPECT_EQ(info.ana_statistics.fec_action_counter,
622 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700623 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
624 stats.ana_statistics.frame_length_increase_counter);
625 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
626 stats.ana_statistics.frame_length_decrease_counter);
627 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
628 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800629 EXPECT_EQ(info.typing_noise_detected,
630 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700631 }
632
633 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
634 webrtc::AudioReceiveStream::Stats stats;
635 stats.remote_ssrc = 123;
636 stats.bytes_rcvd = 456;
637 stats.packets_rcvd = 768;
638 stats.packets_lost = 101;
639 stats.fraction_lost = 23.45f;
640 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100641 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700642 stats.ext_seqnum = 678;
643 stats.jitter_ms = 901;
644 stats.jitter_buffer_ms = 234;
645 stats.jitter_buffer_preferred_ms = 567;
646 stats.delay_estimate_ms = 890;
647 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700648 stats.total_samples_received = 5678901;
649 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200650 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200651 stats.jitter_buffer_delay_seconds = 34;
Chen Xing0acffb52019-01-15 15:46:29 +0100652 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700653 stats.expand_rate = 5.67f;
654 stats.speech_expand_rate = 8.90f;
655 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200656 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700657 stats.accelerate_rate = 4.56f;
658 stats.preemptive_expand_rate = 7.89f;
659 stats.decoding_calls_to_silence_generator = 12;
660 stats.decoding_calls_to_neteq = 345;
661 stats.decoding_normal = 67890;
662 stats.decoding_plc = 1234;
663 stats.decoding_cng = 5678;
664 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700665 stats.decoding_muted_output = 3456;
666 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200667 return stats;
668 }
669 void SetAudioReceiveStreamStats() {
670 for (auto* s : call_.GetAudioReceiveStreams()) {
671 s->SetStats(GetAudioReceiveStreamStats());
672 }
673 }
674 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700675 const auto stats = GetAudioReceiveStreamStats();
676 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
677 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200678 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
679 stats.packets_rcvd);
680 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
681 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700682 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
683 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800684 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200685 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
686 stats.ext_seqnum);
687 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
688 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
689 stats.jitter_buffer_ms);
690 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700691 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
693 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700694 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700695 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
696 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200697 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200698 EXPECT_EQ(info.jitter_buffer_delay_seconds,
699 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100700 EXPECT_EQ(info.jitter_buffer_emitted_count,
701 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700702 EXPECT_EQ(info.expand_rate, stats.expand_rate);
703 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
704 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200705 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700706 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
707 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200708 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700709 stats.decoding_calls_to_silence_generator);
710 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
711 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
712 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
713 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
714 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700715 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700716 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200717 }
hbos1acfbd22016-11-17 23:43:29 -0800718 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
719 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
720 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
721 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
722 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
723 codec.ToCodecParameters());
724 }
725 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
726 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
727 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
728 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
729 codec.ToCodecParameters());
730 }
731 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200732
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100733 void VerifyGainControlEnabledCorrectly() {
734 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
735 EXPECT_EQ(kDefaultAgcMode, apm_config_.gain_controller1.mode);
736 EXPECT_EQ(0, apm_config_.gain_controller1.analog_level_minimum);
737 EXPECT_EQ(255, apm_config_.gain_controller1.analog_level_maximum);
738 }
739
740 void VerifyGainControlDefaultSettings() {
741 EXPECT_EQ(3, apm_config_.gain_controller1.target_level_dbfs);
742 EXPECT_EQ(9, apm_config_.gain_controller1.compression_gain_db);
743 EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
744 }
745
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200746 bool IsEchoCancellationEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100747 return apm_config_.echo_canceller.enabled;
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200748 }
749
peah8271d042016-11-22 07:24:52 -0800750 bool IsHighPassFilterEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100751 return apm_config_.high_pass_filter.enabled;
peah8271d042016-11-22 07:24:52 -0800752 }
753
Sam Zackrissonba502232019-01-04 10:36:48 +0100754 bool IsTypingDetectionEnabled() {
Sam Zackrissonf0d1c032019-03-27 13:28:08 +0100755 return apm_config_.voice_detection.enabled;
Sam Zackrissonba502232019-01-04 10:36:48 +0100756 }
757
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700759 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700760 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800761 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200762 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700763 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700764 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200765 cricket::AudioSendParameters send_parameters_;
766 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800767 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700768 webrtc::AudioProcessing::Config apm_config_;
769
stefanba4c0e42016-02-04 04:12:24 -0800770 private:
771 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772};
773
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100775TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700776 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777}
778
solenberg31fec402016-05-06 02:13:12 -0700779// Test that we can add a send stream and that it has the correct defaults.
780TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
781 EXPECT_TRUE(SetupChannel());
782 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800783 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
784 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
785 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700786 EXPECT_EQ("", config.rtp.c_name);
787 EXPECT_EQ(0u, config.rtp.extensions.size());
788 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
789 config.send_transport);
790}
791
792// Test that we can add a receive stream and that it has the correct defaults.
793TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
794 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800795 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700796 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800797 GetRecvStreamConfig(kSsrcX);
798 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700799 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
800 EXPECT_FALSE(config.rtp.transport_cc);
801 EXPECT_EQ(0u, config.rtp.extensions.size());
802 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
803 config.rtcp_send_transport);
804 EXPECT_EQ("", config.sync_group);
805}
806
stefanba4c0e42016-02-04 04:12:24 -0800807TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700808 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800809 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100810 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800811 if (codec.name == "opus") {
812 EXPECT_TRUE(HasTransportCc(codec));
813 opus_found = true;
814 }
815 }
816 EXPECT_TRUE(opus_found);
817}
818
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819// Test that we set our inbound codecs properly, including changing PT.
820TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700821 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200822 cricket::AudioRecvParameters parameters;
823 parameters.codecs.push_back(kIsacCodec);
824 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800825 parameters.codecs.push_back(kTelephoneEventCodec1);
826 parameters.codecs.push_back(kTelephoneEventCodec2);
827 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 parameters.codecs[2].id = 126;
829 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800830 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700831 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
832 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
833 {{0, {"PCMU", 8000, 1}},
834 {106, {"ISAC", 16000, 1}},
835 {126, {"telephone-event", 8000, 1}},
836 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839// Test that we fail to set an unknown inbound codec.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700844 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846}
847
848// Test that we fail if we have duplicate types in the inbound list.
849TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700850 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200851 cricket::AudioRecvParameters parameters;
852 parameters.codecs.push_back(kIsacCodec);
853 parameters.codecs.push_back(kCn16000Codec);
854 parameters.codecs[1].id = kIsacCodec.id;
855 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we can decode OPUS without stereo parameters.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kPcmuCodec);
864 parameters.codecs.push_back(kOpusCodec);
865 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800866 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700867 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
868 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
869 {{0, {"PCMU", 8000, 1}},
870 {103, {"ISAC", 16000, 1}},
871 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872}
873
874// Test that we can decode OPUS with stereo = 0.
875TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700876 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200877 cricket::AudioRecvParameters parameters;
878 parameters.codecs.push_back(kIsacCodec);
879 parameters.codecs.push_back(kPcmuCodec);
880 parameters.codecs.push_back(kOpusCodec);
881 parameters.codecs[2].params["stereo"] = "0";
882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800883 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700884 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
885 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
886 {{0, {"PCMU", 8000, 1}},
887 {103, {"ISAC", 16000, 1}},
888 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889}
890
891// Test that we can decode OPUS with stereo = 1.
892TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700893 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 cricket::AudioRecvParameters parameters;
895 parameters.codecs.push_back(kIsacCodec);
896 parameters.codecs.push_back(kPcmuCodec);
897 parameters.codecs.push_back(kOpusCodec);
898 parameters.codecs[2].params["stereo"] = "1";
899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800900 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700901 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
902 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
903 {{0, {"PCMU", 8000, 1}},
904 {103, {"ISAC", 16000, 1}},
905 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906}
907
908// Test that changes to recv codecs are applied to all streams.
909TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700910 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 cricket::AudioRecvParameters parameters;
912 parameters.codecs.push_back(kIsacCodec);
913 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800914 parameters.codecs.push_back(kTelephoneEventCodec1);
915 parameters.codecs.push_back(kTelephoneEventCodec2);
916 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 parameters.codecs[2].id = 126;
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700919 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
920 EXPECT_TRUE(AddRecvStream(ssrc));
921 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
922 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
923 {{0, {"PCMU", 8000, 1}},
924 {106, {"ISAC", 16000, 1}},
925 {126, {"telephone-event", 8000, 1}},
926 {107, {"telephone-event", 32000, 1}}})));
927 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928}
929
930TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700931 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200932 cricket::AudioRecvParameters parameters;
933 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800934 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
solenberg2100c0b2017-03-01 11:29:29 -0800937 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200938 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800939 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
942// Test that we can apply the same set of codecs again while playing.
943TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700944 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200945 cricket::AudioRecvParameters parameters;
946 parameters.codecs.push_back(kIsacCodec);
947 parameters.codecs.push_back(kCn16000Codec);
948 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700949 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200950 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
deadbeefcb383672017-04-26 16:28:42 -0700952 // Remapping a payload type to a different codec should fail.
953 parameters.codecs[0] = kOpusCodec;
954 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800956 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957}
958
959// Test that we can add a codec while playing.
960TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700961 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 cricket::AudioRecvParameters parameters;
963 parameters.codecs.push_back(kIsacCodec);
964 parameters.codecs.push_back(kCn16000Codec);
965 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700966 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200968 parameters.codecs.push_back(kOpusCodec);
969 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800970 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971}
972
deadbeefcb383672017-04-26 16:28:42 -0700973// Test that we accept adding the same codec with a different payload type.
974// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
975TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
976 EXPECT_TRUE(SetupRecvStream());
977 cricket::AudioRecvParameters parameters;
978 parameters.codecs.push_back(kIsacCodec);
979 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
980
981 ++parameters.codecs[0].id;
982 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
983}
984
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000988 // Test that when autobw is enabled, bitrate is kept as the default
989 // value. autobw is enabled for the following tests because the target
990 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991
992 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700993 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994
995 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700996 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997
ossu20a4b3f2017-04-27 02:08:52 -0700998 // opus, default bitrate == 32000 in mono.
999 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000}
1001
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001006 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1007 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001008 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001011 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1012 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1013 // Rates above the max (510000) should be capped.
1014 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015}
1016
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001017TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001018 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001019
1020 // Test that we can only set a maximum bitrate for a fixed-rate codec
1021 // if it's bigger than the fixed rate.
1022
1023 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001024 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1025 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1026 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1027 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1028 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1029 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1030 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001031}
1032
1033TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001034 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001035 const int kDesiredBitrate = 128000;
1036 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001037 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001038 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001039 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001040
Yves Gerey665174f2018-06-19 15:03:05 +02001041 EXPECT_TRUE(
1042 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001043
solenberg2100c0b2017-03-01 11:29:29 -08001044 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001045}
1046
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001047// Test that bitrate cannot be set for CBR codecs.
1048// Bitrate is ignored if it is higher than the fixed bitrate.
1049// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001050TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001051 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001052
1053 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001054 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001055 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001056
1057 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001058 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001059 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001060
1061 send_parameters_.max_bandwidth_bps = 128;
1062 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001064}
1065
skvlade0d46372016-04-07 22:59:22 -07001066// Test that the per-stream bitrate limit and the global
1067// bitrate limit both apply.
1068TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1069 EXPECT_TRUE(SetupSendStream());
1070
ossu20a4b3f2017-04-27 02:08:52 -07001071 // opus, default bitrate == 32000.
1072 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001073 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1074 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1075 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1076
1077 // CBR codecs allow both maximums to exceed the bitrate.
1078 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1079 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1080 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1081 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1082
1083 // CBR codecs don't allow per stream maximums to be too low.
1084 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1085 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1086}
1087
1088// Test that an attempt to set RtpParameters for a stream that does not exist
1089// fails.
1090TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1091 EXPECT_TRUE(SetupChannel());
1092 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001093 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001094 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001095
1096 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001097 EXPECT_FALSE(
1098 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001099}
1100
1101TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001102 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001103 // This test verifies that setting RtpParameters succeeds only if
1104 // the structure contains exactly one encoding.
1105 // TODO(skvlad): Update this test when we start supporting setting parameters
1106 // for each encoding individually.
1107
1108 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001109 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001110 // Two or more encodings should result in failure.
1111 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001112 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001113 // Zero encodings should also fail.
1114 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001115 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001116}
1117
1118// Changing the SSRC through RtpParameters is not allowed.
1119TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1120 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001122 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001123 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001124}
1125
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001126// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001128TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1129 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001130 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001131 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001132 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001134 ASSERT_EQ(1u, parameters.encodings.size());
1135 ASSERT_TRUE(parameters.encodings[0].active);
1136 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001137 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001138 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001139
1140 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001141 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001142 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001143 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001144 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001145 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001146}
1147
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001148// Test that SetRtpSendParameters configures the correct encoding channel for
1149// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001150TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1151 SetupForMultiSendStream();
1152 // Create send streams.
1153 for (uint32_t ssrc : kSsrcs4) {
1154 EXPECT_TRUE(
1155 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1156 }
1157 // Configure one stream to be limited by the stream config, another to be
1158 // limited by the global max, and the third one with no per-stream limit
1159 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001160 SetGlobalMaxBitrate(kOpusCodec, 32000);
1161 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1162 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001163 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1164
ossu20a4b3f2017-04-27 02:08:52 -07001165 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1166 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1167 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001168
1169 // Remove the global cap; the streams should switch to their respective
1170 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001171 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001172 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1173 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1174 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001175}
1176
Tim Haloun648d28a2018-10-18 16:52:22 -07001177// RTCRtpEncodingParameters.network_priority must be one of a few values
1178// derived from the default priority, corresponding to very-low, low, medium,
1179// or high.
1180TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1181 EXPECT_TRUE(SetupSendStream());
1182 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1183 EXPECT_EQ(1UL, parameters.encodings.size());
1184 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1185 parameters.encodings[0].network_priority);
1186
1187 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1188 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1189 for (auto it : good_values) {
1190 parameters.encodings[0].network_priority = it;
1191 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1192 }
1193 for (auto it : bad_values) {
1194 parameters.encodings[0].network_priority = it;
1195 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1196 }
1197}
1198
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199// Test that GetRtpSendParameters returns the currently configured codecs.
1200TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001201 EXPECT_TRUE(SetupSendStream());
1202 cricket::AudioSendParameters parameters;
1203 parameters.codecs.push_back(kIsacCodec);
1204 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001205 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001206
solenberg2100c0b2017-03-01 11:29:29 -08001207 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001208 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1210 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001211}
1212
Florent Castellidacec712018-05-24 16:24:21 +02001213// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1214TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1215 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1216 params.cname = "rtcpcname";
1217 EXPECT_TRUE(SetupSendStream(params));
1218
1219 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1220 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1221}
1222
Florent Castelliabe301f2018-06-12 18:33:49 +02001223TEST_F(WebRtcVoiceEngineTestFake,
1224 DetectRtpSendParameterHeaderExtensionsChange) {
1225 EXPECT_TRUE(SetupSendStream());
1226
1227 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1228 rtp_parameters.header_extensions.emplace_back();
1229
1230 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1231
1232 webrtc::RTCError result =
1233 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1234 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1235}
1236
deadbeefcb443432016-12-12 11:12:36 -08001237// Test that GetRtpSendParameters returns an SSRC.
1238TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1239 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001240 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001241 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001242 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001243}
1244
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001245// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001246TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001247 EXPECT_TRUE(SetupSendStream());
1248 cricket::AudioSendParameters parameters;
1249 parameters.codecs.push_back(kIsacCodec);
1250 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001251 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001252
solenberg2100c0b2017-03-01 11:29:29 -08001253 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001254
1255 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001256 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001258 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001259 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1260 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001261}
1262
minyuececec102017-03-27 13:04:25 -07001263// Test that max_bitrate_bps in send stream config gets updated correctly when
1264// SetRtpSendParameters is called.
1265TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1266 webrtc::test::ScopedFieldTrials override_field_trials(
1267 "WebRTC-Audio-SendSideBwe/Enabled/");
1268 EXPECT_TRUE(SetupSendStream());
1269 cricket::AudioSendParameters send_parameters;
1270 send_parameters.codecs.push_back(kOpusCodec);
1271 SetSendParameters(send_parameters);
1272
1273 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1274 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1275 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1276
1277 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001278 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001279 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001280
1281 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1282 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1283}
1284
Seth Hampson24722b32017-12-22 09:36:42 -08001285// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1286// a value <= 0, setting the parameters returns false.
1287TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1288 EXPECT_TRUE(SetupSendStream());
1289 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1290 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1291 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1292 rtp_parameters.encodings[0].bitrate_priority);
1293
1294 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001295 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001296 rtp_parameters.encodings[0].bitrate_priority = -1.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}
1299
1300// Test that the bitrate_priority in the send stream config gets updated when
1301// SetRtpSendParameters is set for the VoiceMediaChannel.
1302TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1303 EXPECT_TRUE(SetupSendStream());
1304 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1305
1306 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1307 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1308 rtp_parameters.encodings[0].bitrate_priority);
1309 double new_bitrate_priority = 2.0;
1310 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001311 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001312
1313 // The priority should get set for both the audio channel's rtp parameters
1314 // and the audio send stream's audio config.
1315 EXPECT_EQ(
1316 new_bitrate_priority,
1317 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1318 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1319}
1320
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001321// Test that GetRtpReceiveParameters returns the currently configured codecs.
1322TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1323 EXPECT_TRUE(SetupRecvStream());
1324 cricket::AudioRecvParameters parameters;
1325 parameters.codecs.push_back(kIsacCodec);
1326 parameters.codecs.push_back(kPcmuCodec);
1327 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1328
1329 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001330 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001331 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1332 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1333 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1334}
1335
deadbeefcb443432016-12-12 11:12:36 -08001336// Test that GetRtpReceiveParameters returns an SSRC.
1337TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1338 EXPECT_TRUE(SetupRecvStream());
1339 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001340 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001341 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001342 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001343}
1344
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001345// Test that if we set/get parameters multiple times, we get the same results.
1346TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1347 EXPECT_TRUE(SetupRecvStream());
1348 cricket::AudioRecvParameters parameters;
1349 parameters.codecs.push_back(kIsacCodec);
1350 parameters.codecs.push_back(kPcmuCodec);
1351 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1352
1353 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001354 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001355
1356 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001357 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001358
1359 // ... And this shouldn't change the params returned by
1360 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001361 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1362 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001363}
1364
deadbeef3bc15102017-04-20 19:25:07 -07001365// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1366// aren't signaled. It should return an empty "RtpEncodingParameters" when
1367// configured to receive an unsignaled stream and no packets have been received
1368// yet, and start returning the SSRC once a packet has been received.
1369TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1370 ASSERT_TRUE(SetupChannel());
1371 // Call necessary methods to configure receiving a default stream as
1372 // soon as it arrives.
1373 cricket::AudioRecvParameters parameters;
1374 parameters.codecs.push_back(kIsacCodec);
1375 parameters.codecs.push_back(kPcmuCodec);
1376 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1377
1378 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1379 // stream. Should return nothing.
1380 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1381
1382 // Set a sink for an unsignaled stream.
1383 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1384 // Value of "0" means "unsignaled stream".
1385 channel_->SetRawAudioSink(0, std::move(fake_sink));
1386
1387 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1388 // in this method means "unsignaled stream".
1389 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1390 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1391 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1392
1393 // Receive PCMU packet (SSRC=1).
1394 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1395
1396 // The |ssrc| member should still be unset.
1397 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1398 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1399 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1400}
1401
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402// Test that we apply codecs properly.
1403TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001404 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 cricket::AudioSendParameters parameters;
1406 parameters.codecs.push_back(kIsacCodec);
1407 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001408 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001410 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001411 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001412 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1413 EXPECT_EQ(96, send_codec_spec.payload_type);
1414 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1415 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1416 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001417 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001418 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419}
1420
ossu20a4b3f2017-04-27 02:08:52 -07001421// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1422// AudioSendStream.
1423TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kIsacCodec);
1427 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001428 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 parameters.codecs[0].id = 96;
1430 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001431 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001434 // Calling SetSendCodec again with same codec which is already set.
1435 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001436 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001437 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001438}
1439
ossu20a4b3f2017-04-27 02:08:52 -07001440// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1441// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001442
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001443// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].bitrate = 0;
1449 parameters.codecs[0].clockrate = 50000;
1450 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001453// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 0;
1459 parameters.codecs[0].channels = 0;
1460 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001463// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 0;
1469 parameters.codecs[0].channels = 0;
1470 parameters.codecs[0].params["stereo"] = "1";
1471 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472}
1473
1474// Test that if channel is 1 for opus and there's no stereo, we fail.
1475TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001476 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 cricket::AudioSendParameters parameters;
1478 parameters.codecs.push_back(kOpusCodec);
1479 parameters.codecs[0].bitrate = 0;
1480 parameters.codecs[0].channels = 1;
1481 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
1484// Test that if channel is 1 for opus and stereo=0, we fail.
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].channels = 1;
1491 parameters.codecs[0].params["stereo"] = "0";
1492 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
1495// Test that if channel is 1 for opus and stereo=1, we fail.
1496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001497 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 cricket::AudioSendParameters parameters;
1499 parameters.codecs.push_back(kOpusCodec);
1500 parameters.codecs[0].bitrate = 0;
1501 parameters.codecs[0].channels = 1;
1502 parameters.codecs[0].params["stereo"] = "1";
1503 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001504}
1505
ossu20a4b3f2017-04-27 02:08:52 -07001506// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001507TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001508 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001509 cricket::AudioSendParameters parameters;
1510 parameters.codecs.push_back(kOpusCodec);
1511 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001512 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001513 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].bitrate = 0;
1522 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001524 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001525}
1526
ossu20a4b3f2017-04-27 02:08:52 -07001527// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001529 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001530 cricket::AudioSendParameters parameters;
1531 parameters.codecs.push_back(kOpusCodec);
1532 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001533 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001534 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001535 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001536 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001537
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001538 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001540 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001541}
1542
ossu20a4b3f2017-04-27 02:08:52 -07001543// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].bitrate = 0;
1549 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001550 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001551 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552}
1553
ossu20a4b3f2017-04-27 02:08:52 -07001554// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001555TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001556 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001557 cricket::AudioSendParameters parameters;
1558 parameters.codecs.push_back(kOpusCodec);
1559 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001560 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001561 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001563 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001564
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001565 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001566 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001567 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001568}
1569
ossu20a4b3f2017-04-27 02:08:52 -07001570// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001571TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001572 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 cricket::AudioSendParameters parameters;
1574 parameters.codecs.push_back(kOpusCodec);
1575 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001577 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1578 EXPECT_EQ(111, spec.payload_type);
1579 EXPECT_EQ(96000, spec.target_bitrate_bps);
1580 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001581 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001582 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
ossu20a4b3f2017-04-27 02:08:52 -07001585// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001587 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 cricket::AudioSendParameters parameters;
1589 parameters.codecs.push_back(kOpusCodec);
1590 parameters.codecs[0].bitrate = 30000;
1591 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001593 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001594}
1595
ossu20a4b3f2017-04-27 02:08:52 -07001596// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001598 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 cricket::AudioSendParameters parameters;
1600 parameters.codecs.push_back(kOpusCodec);
1601 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001603 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
ossu20a4b3f2017-04-27 02:08:52 -07001606// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters parameters;
1610 parameters.codecs.push_back(kOpusCodec);
1611 parameters.codecs[0].bitrate = 30000;
1612 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001613 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001614 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001615}
1616
stefan13f1a0a2016-11-30 07:22:58 -08001617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1618 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1619 200000);
1620}
1621
1622TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1623 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1624}
1625
1626TEST_F(WebRtcVoiceEngineTestFake,
1627 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1628 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1629}
1630
1631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1632 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1633}
1634
Yves Gerey665174f2018-06-19 15:03:05 +02001635TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001636 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1637 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001638 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001639 // Setting max bitrate should keep previous min bitrate
1640 // Setting max bitrate should not reset start bitrate.
1641 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1642 SetSdpBitrateParameters(
1643 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1644 Field(&BitrateConstraints::start_bitrate_bps, -1),
1645 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001646 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001647}
1648
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001649// Test that we can enable NACK with opus as callee.
1650TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001651 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001652 cricket::AudioSendParameters parameters;
1653 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001654 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1655 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001656 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001658 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001659 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001660
Yves Gerey665174f2018-06-19 15:03:05 +02001661 EXPECT_TRUE(
1662 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001663}
1664
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665// Test that we can enable NACK on receive streams.
1666TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001667 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001668 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 cricket::AudioSendParameters parameters;
1670 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001671 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1672 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001673 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001674 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001676}
1677
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678// Test that we can disable NACK on receive streams.
1679TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001680 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001681 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001682 cricket::AudioSendParameters parameters;
1683 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001684 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1685 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001687 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 parameters.codecs.clear();
1690 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001692 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693}
1694
1695// Test that NACK is enabled on a new receive stream.
1696TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001697 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001698 cricket::AudioSendParameters parameters;
1699 parameters.codecs.push_back(kIsacCodec);
1700 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001701 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1702 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001704
solenberg2100c0b2017-03-01 11:29:29 -08001705 EXPECT_TRUE(AddRecvStream(kSsrcY));
1706 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1707 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1708 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709}
1710
stefanba4c0e42016-02-04 04:12:24 -08001711TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001712 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001713 cricket::AudioSendParameters send_parameters;
1714 send_parameters.codecs.push_back(kOpusCodec);
1715 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001717
1718 cricket::AudioRecvParameters recv_parameters;
1719 recv_parameters.codecs.push_back(kIsacCodec);
1720 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001721 EXPECT_TRUE(AddRecvStream(kSsrcX));
1722 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001723 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001724 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001725
ossudedfd282016-06-14 07:12:39 -07001726 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001728 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001729 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001730 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001731}
1732
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001733// Test that we can switch back and forth between Opus and ISAC with CN.
1734TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001735 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001736
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 cricket::AudioSendParameters opus_parameters;
1738 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001740 {
ossu20a4b3f2017-04-27 02:08:52 -07001741 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1742 EXPECT_EQ(111, spec.payload_type);
1743 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001744 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001746 cricket::AudioSendParameters isac_parameters;
1747 isac_parameters.codecs.push_back(kIsacCodec);
1748 isac_parameters.codecs.push_back(kCn16000Codec);
1749 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001751 {
ossu20a4b3f2017-04-27 02:08:52 -07001752 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1753 EXPECT_EQ(103, spec.payload_type);
1754 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001755 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001758 {
ossu20a4b3f2017-04-27 02:08:52 -07001759 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1760 EXPECT_EQ(111, spec.payload_type);
1761 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763}
1764
1765// Test that we handle various ways of specifying bitrate.
1766TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 cricket::AudioSendParameters parameters;
1769 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001771 {
ossu20a4b3f2017-04-27 02:08:52 -07001772 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1773 EXPECT_EQ(103, spec.payload_type);
1774 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1775 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001776 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001777
Yves Gerey665174f2018-06-19 15:03:05 +02001778 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001779 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001780 {
ossu20a4b3f2017-04-27 02:08:52 -07001781 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1782 EXPECT_EQ(103, spec.payload_type);
1783 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1784 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001785 }
Yves Gerey665174f2018-06-19 15:03:05 +02001786 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001788 {
ossu20a4b3f2017-04-27 02:08:52 -07001789 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1790 EXPECT_EQ(103, spec.payload_type);
1791 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1792 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001793 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794
Yves Gerey665174f2018-06-19 15:03:05 +02001795 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001796 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001797 {
ossu20a4b3f2017-04-27 02:08:52 -07001798 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1799 EXPECT_EQ(0, spec.payload_type);
1800 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1801 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001802 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001803
Yves Gerey665174f2018-06-19 15:03:05 +02001804 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001805 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001806 {
ossu20a4b3f2017-04-27 02:08:52 -07001807 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1808 EXPECT_EQ(0, spec.payload_type);
1809 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1810 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001811 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001812
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001814 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001816 {
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(111, spec.payload_type);
1819 EXPECT_STREQ("opus", spec.format.name.c_str());
1820 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001821 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001822}
1823
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001824// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001826 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 cricket::AudioSendParameters parameters;
1828 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001829}
1830
1831// Test that we can set send codecs even with telephone-event codec as the first
1832// one on the list.
1833TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001834 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001835 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001836 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 parameters.codecs.push_back(kIsacCodec);
1838 parameters.codecs.push_back(kPcmuCodec);
1839 parameters.codecs[0].id = 98; // DTMF
1840 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001841 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001842 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1843 EXPECT_EQ(96, spec.payload_type);
1844 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001845 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001846 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001847}
1848
Harald Alvestranda1f66612018-02-21 11:24:23 +01001849// Test that CanInsertDtmf() is governed by the send flag
1850TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1851 EXPECT_TRUE(SetupSendStream());
1852 cricket::AudioSendParameters parameters;
1853 parameters.codecs.push_back(kTelephoneEventCodec1);
1854 parameters.codecs.push_back(kPcmuCodec);
1855 parameters.codecs[0].id = 98; // DTMF
1856 parameters.codecs[1].id = 96;
1857 SetSendParameters(parameters);
1858 EXPECT_FALSE(channel_->CanInsertDtmf());
1859 SetSend(true);
1860 EXPECT_TRUE(channel_->CanInsertDtmf());
1861 SetSend(false);
1862 EXPECT_FALSE(channel_->CanInsertDtmf());
1863}
1864
solenberg31642aa2016-03-14 08:00:37 -07001865// Test that payload type range is limited for telephone-event codec.
1866TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001867 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001868 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001869 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001870 parameters.codecs.push_back(kIsacCodec);
1871 parameters.codecs[0].id = 0; // DTMF
1872 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001874 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001875 EXPECT_TRUE(channel_->CanInsertDtmf());
1876 parameters.codecs[0].id = 128; // DTMF
1877 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1878 EXPECT_FALSE(channel_->CanInsertDtmf());
1879 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001881 EXPECT_TRUE(channel_->CanInsertDtmf());
1882 parameters.codecs[0].id = -1; // DTMF
1883 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1884 EXPECT_FALSE(channel_->CanInsertDtmf());
1885}
1886
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001887// Test that we can set send codecs even with CN codec as the first
1888// one on the list.
1889TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001890 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 cricket::AudioSendParameters parameters;
1892 parameters.codecs.push_back(kCn16000Codec);
1893 parameters.codecs.push_back(kIsacCodec);
1894 parameters.codecs.push_back(kPcmuCodec);
1895 parameters.codecs[0].id = 98; // wideband CN
1896 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001898 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1899 EXPECT_EQ(96, send_codec_spec.payload_type);
1900 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001901 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001902}
1903
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001904// Test that we set VAD and DTMF types correctly as caller.
1905TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001906 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001907 cricket::AudioSendParameters parameters;
1908 parameters.codecs.push_back(kIsacCodec);
1909 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 parameters.codecs.push_back(kCn16000Codec);
1912 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001913 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 parameters.codecs[0].id = 96;
1915 parameters.codecs[2].id = 97; // wideband CN
1916 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001917 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001918 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1919 EXPECT_EQ(96, send_codec_spec.payload_type);
1920 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001921 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001922 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001923 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001924 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925}
1926
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001927// Test that we set VAD and DTMF types correctly as callee.
1928TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001929 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 cricket::AudioSendParameters parameters;
1931 parameters.codecs.push_back(kIsacCodec);
1932 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001933 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 parameters.codecs.push_back(kCn16000Codec);
1935 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001936 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 parameters.codecs[0].id = 96;
1938 parameters.codecs[2].id = 97; // wideband CN
1939 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001940 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001941 EXPECT_TRUE(
1942 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001943
ossu20a4b3f2017-04-27 02:08:52 -07001944 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1945 EXPECT_EQ(96, send_codec_spec.payload_type);
1946 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001947 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001948 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001949 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001950 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001951}
1952
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001953// Test that we only apply VAD if we have a CN codec that matches the
1954// send codec clockrate.
1955TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001956 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 parameters.codecs.push_back(kIsacCodec);
1960 parameters.codecs.push_back(kCn16000Codec);
1961 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001962 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001963 {
ossu20a4b3f2017-04-27 02:08:52 -07001964 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1965 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001966 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001967 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001968 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001972 {
ossu20a4b3f2017-04-27 02:08:52 -07001973 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1974 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001975 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001976 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001977 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001978 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001979 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001980 {
ossu20a4b3f2017-04-27 02:08:52 -07001981 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1982 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001983 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001984 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001985 }
Brave Yao5225dd82015-03-26 07:39:19 +08001986 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001987 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001988 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001989 {
ossu20a4b3f2017-04-27 02:08:52 -07001990 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1991 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001992 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001993 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001994}
1995
1996// Test that we perform case-insensitive matching of codec names.
1997TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001998 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 cricket::AudioSendParameters parameters;
2000 parameters.codecs.push_back(kIsacCodec);
2001 parameters.codecs.push_back(kPcmuCodec);
2002 parameters.codecs.push_back(kCn16000Codec);
2003 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002004 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002005 parameters.codecs[0].name = "iSaC";
2006 parameters.codecs[0].id = 96;
2007 parameters.codecs[2].id = 97; // wideband CN
2008 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002009 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002010 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2011 EXPECT_EQ(96, send_codec_spec.payload_type);
2012 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002013 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002014 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002015 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002016 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002017}
2018
stefanba4c0e42016-02-04 04:12:24 -08002019class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2020 public:
2021 WebRtcVoiceEngineWithSendSideBweTest()
2022 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2023};
2024
2025TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2026 SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +01002027 const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
2028 EXPECT_THAT(capabilities.header_extensions,
2029 Contains(testing::Field(
2030 "uri", &RtpExtension::uri,
2031 webrtc::RtpExtension::kTransportSequenceNumberUri)));
stefanba4c0e42016-02-04 04:12:24 -08002032}
2033
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002034// Test support for audio level header extension.
2035TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002036 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002037}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002038TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002039 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002040}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002041
solenbergd4adce42016-11-17 06:26:52 -08002042// Test support for transport sequence number header extension.
2043TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2044 TestSetSendRtpHeaderExtensions(
2045 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002046}
solenbergd4adce42016-11-17 06:26:52 -08002047TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2048 TestSetRecvRtpHeaderExtensions(
2049 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002050}
2051
solenberg1ac56142015-10-13 03:58:19 -07002052// Test that we can create a channel and start sending on it.
2053TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002054 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002055 SetSendParameters(send_parameters_);
2056 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002057 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002058 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002059 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002060}
2061
2062// Test that a channel will send if and only if it has a source and is enabled
2063// for sending.
2064TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002065 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002066 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002067 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002068 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2070 SetAudioSend(kSsrcX, true, &fake_source_);
2071 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2072 SetAudioSend(kSsrcX, true, nullptr);
2073 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002074}
2075
solenberg94218532016-06-16 10:53:22 -07002076// Test that a channel is muted/unmuted.
2077TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2078 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002079 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002080 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2081 SetAudioSend(kSsrcX, true, nullptr);
2082 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2083 SetAudioSend(kSsrcX, false, nullptr);
2084 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002085}
2086
solenberg6d6e7c52016-04-13 09:07:30 -07002087// Test that SetSendParameters() does not alter a stream's send state.
2088TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2089 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002091
2092 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002093 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002095
2096 // Changing RTP header extensions will recreate the AudioSendStream.
2097 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002098 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002099 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002101
2102 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002103 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002105
2106 // Changing RTP header extensions will recreate the AudioSendStream.
2107 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002108 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002109 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002110}
2111
solenberg1ac56142015-10-13 03:58:19 -07002112// Test that we can create a channel and start playing out on it.
2113TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002114 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002115 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002116 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002117 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002118 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120}
2121
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122// Test that we can add and remove send streams.
2123TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2124 SetupForMultiSendStream();
2125
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002127 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128
solenbergc96df772015-10-21 13:01:53 -07002129 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002130 EXPECT_TRUE(
2131 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002132 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002134 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 }
tfarina5237aaf2015-11-10 23:44:30 -08002136 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137
solenbergc96df772015-10-21 13:01:53 -07002138 // Delete the send streams.
2139 for (uint32_t ssrc : kSsrcs4) {
2140 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002141 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002142 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143 }
solenbergc96df772015-10-21 13:01:53 -07002144 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145}
2146
2147// Test SetSendCodecs correctly configure the codecs in all send streams.
2148TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2149 SetupForMultiSendStream();
2150
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002151 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002152 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002153 EXPECT_TRUE(
2154 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 }
2156
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002157 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002159 parameters.codecs.push_back(kIsacCodec);
2160 parameters.codecs.push_back(kCn16000Codec);
2161 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002162 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163
2164 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002165 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002166 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2167 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002168 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2169 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002170 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002171 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002172 }
2173
minyue7a973442016-10-20 03:27:12 -07002174 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002175 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002176 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002177 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002178 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2179 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002180 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2181 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002182 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184}
2185
2186// Test we can SetSend on all send streams correctly.
2187TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2188 SetupForMultiSendStream();
2189
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002190 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002191 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002192 EXPECT_TRUE(
2193 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002194 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002195 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002196 }
2197
2198 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002199 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002200 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002201 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002202 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 }
2204
2205 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002206 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002207 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002209 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002210 }
2211}
2212
2213// Test we can set the correct statistics on all send streams.
2214TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2215 SetupForMultiSendStream();
2216
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002217 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002218 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002219 EXPECT_TRUE(
2220 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002221 }
solenberg85a04962015-10-27 03:35:21 -07002222
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002223 // Create a receive stream to check that none of the send streams end up in
2224 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002226
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002228 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002229 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002230 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002231
solenberg85a04962015-10-27 03:35:21 -07002232 // Check stats for the added streams.
2233 {
2234 cricket::VoiceMediaInfo info;
2235 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002236
solenberg85a04962015-10-27 03:35:21 -07002237 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002238 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002239 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002240 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002241 }
hbos1acfbd22016-11-17 23:43:29 -08002242 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002243
2244 // We have added one receive stream. We should see empty stats.
2245 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002246 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002247 }
solenberg1ac56142015-10-13 03:58:19 -07002248
solenberg2100c0b2017-03-01 11:29:29 -08002249 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002250 {
2251 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002252 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002253 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002254 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002255 EXPECT_EQ(0u, info.receivers.size());
2256 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002257
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002258 // Deliver a new packet - a default receive stream should be created and we
2259 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002260 {
2261 cricket::VoiceMediaInfo info;
2262 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2263 SetAudioReceiveStreamStats();
2264 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002265 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002266 EXPECT_EQ(1u, info.receivers.size());
2267 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002268 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002269 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002270}
2271
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002272// Test that we can add and remove receive streams, and do proper send/playout.
2273// We can receive on multiple streams while sending one stream.
2274TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002275 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002276
solenberg1ac56142015-10-13 03:58:19 -07002277 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002278 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002279 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002280
solenberg1ac56142015-10-13 03:58:19 -07002281 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002282 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002283 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002284 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002285
solenberg1ac56142015-10-13 03:58:19 -07002286 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288
2289 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002290 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2291 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2292 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002293
2294 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002295 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002296 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002297
2298 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002299 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002300 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2301 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002302
aleloi84ef6152016-08-04 05:28:21 -07002303 // Restart playout and make sure recv streams are played out.
2304 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002305 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2306 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307
aleloi84ef6152016-08-04 05:28:21 -07002308 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002309 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2310 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002311}
2312
wu@webrtc.org97077a32013-10-25 21:18:33 +00002313TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002314 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002315 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002316 .Times(testing::AtLeast(1))
Steve Anton606a5972017-12-07 14:31:01 -08002317 .WillRepeatedly(Return(false));
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002318 const auto& agc_config = apm_config_.gain_controller1;
2319
2320 // Ensure default options.
2321 VerifyGainControlEnabledCorrectly();
2322 VerifyGainControlDefaultSettings();
2323
2324 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002325 SetSendParameters(send_parameters_);
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002326 EXPECT_FALSE(agc_config.enabled);
2327 send_parameters_.options.auto_gain_control = absl::nullopt;
2328
2329 send_parameters_.options.tx_agc_target_dbov = 5;
2330 SetSendParameters(send_parameters_);
2331 EXPECT_EQ(5, agc_config.target_level_dbfs);
2332 send_parameters_.options.tx_agc_target_dbov = absl::nullopt;
2333
2334 send_parameters_.options.tx_agc_digital_compression_gain = 10;
2335 SetSendParameters(send_parameters_);
2336 EXPECT_EQ(10, agc_config.compression_gain_db);
2337 send_parameters_.options.tx_agc_digital_compression_gain = absl::nullopt;
2338
2339 send_parameters_.options.tx_agc_limiter = false;
2340 SetSendParameters(send_parameters_);
2341 EXPECT_FALSE(agc_config.enable_limiter);
2342 send_parameters_.options.tx_agc_limiter = absl::nullopt;
2343
2344 SetSendParameters(send_parameters_);
2345 // Expect all options to have been preserved.
2346 EXPECT_FALSE(agc_config.enabled);
2347 EXPECT_EQ(5, agc_config.target_level_dbfs);
2348 EXPECT_EQ(10, agc_config.compression_gain_db);
2349 EXPECT_FALSE(agc_config.enable_limiter);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002350}
2351
minyue6b825df2016-10-31 04:08:32 -07002352TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2353 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002354 send_parameters_.options.audio_network_adaptor = true;
2355 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002356 SetSendParameters(send_parameters_);
2357 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002358 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002359}
2360
2361TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2362 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002363 send_parameters_.options.audio_network_adaptor = true;
2364 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002365 SetSendParameters(send_parameters_);
2366 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002367 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002368 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002369 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002370 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002371 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002372}
2373
2374TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2375 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002376 send_parameters_.options.audio_network_adaptor = true;
2377 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002378 SetSendParameters(send_parameters_);
2379 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002380 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002381 const int initial_num = call_.GetNumCreatedSendStreams();
2382 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002383 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002384 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2385 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002386 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002387 // AudioSendStream not expected to be recreated.
2388 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2389 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002391}
2392
michaelt6672b262017-01-11 10:17:59 -08002393class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2394 : public WebRtcVoiceEngineTestFake {
2395 public:
2396 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2397 : WebRtcVoiceEngineTestFake(
2398 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2399 "Enabled/") {}
2400};
2401
2402TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2403 EXPECT_TRUE(SetupSendStream());
2404 cricket::AudioSendParameters parameters;
2405 parameters.codecs.push_back(kOpusCodec);
2406 SetSendParameters(parameters);
2407 const int initial_num = call_.GetNumCreatedSendStreams();
2408 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2409
2410 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2411 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002412 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2413 constexpr int kMinOverheadBps =
2414 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002415
2416 constexpr int kOpusMinBitrateBps = 6000;
2417 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002418 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002419 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002420 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002421 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002422
Oskar Sundbom78807582017-11-16 11:09:55 +01002423 parameters.options.audio_network_adaptor = true;
2424 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002425 SetSendParameters(parameters);
2426
ossu11bfc532017-02-16 05:37:06 -08002427 constexpr int kMinOverheadWithAnaBps =
2428 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002429
2430 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002431 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002432
minyuececec102017-03-27 13:04:25 -07002433 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002434 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002435}
2436
minyuececec102017-03-27 13:04:25 -07002437// This test is similar to
2438// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2439// additional field trial.
2440TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2441 SetRtpSendParameterUpdatesMaxBitrate) {
2442 EXPECT_TRUE(SetupSendStream());
2443 cricket::AudioSendParameters send_parameters;
2444 send_parameters.codecs.push_back(kOpusCodec);
2445 SetSendParameters(send_parameters);
2446
2447 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2448 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2449 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2450
2451 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002452 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002453 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002454
2455 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2456#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2457 constexpr int kMinOverhead = 3333;
2458#else
2459 constexpr int kMinOverhead = 6666;
2460#endif
2461 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2462}
2463
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002465// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002467 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002468 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469}
2470
2471TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2472 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002473 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002474 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002475 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002476 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002477 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002478 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002479 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480
solenberg85a04962015-10-27 03:35:21 -07002481 // Check stats for the added streams.
2482 {
2483 cricket::VoiceMediaInfo info;
2484 EXPECT_EQ(true, channel_->GetStats(&info));
2485
2486 // We have added one send stream. We should see the stats we've set.
2487 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002488 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002489 // We have added one receive stream. We should see empty stats.
2490 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002491 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002492 }
solenberg1ac56142015-10-13 03:58:19 -07002493
solenberg566ef242015-11-06 15:34:49 -08002494 // Start sending - this affects some reported stats.
2495 {
2496 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002497 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002498 EXPECT_EQ(true, channel_->GetStats(&info));
2499 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002500 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002501 }
2502
solenberg2100c0b2017-03-01 11:29:29 -08002503 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002504 {
2505 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002506 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002507 EXPECT_EQ(true, channel_->GetStats(&info));
2508 EXPECT_EQ(1u, info.senders.size());
2509 EXPECT_EQ(0u, info.receivers.size());
2510 }
solenberg1ac56142015-10-13 03:58:19 -07002511
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002512 // Deliver a new packet - a default receive stream should be created and we
2513 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002514 {
2515 cricket::VoiceMediaInfo info;
2516 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2517 SetAudioReceiveStreamStats();
2518 EXPECT_EQ(true, channel_->GetStats(&info));
2519 EXPECT_EQ(1u, info.senders.size());
2520 EXPECT_EQ(1u, info.receivers.size());
2521 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002522 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002523 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524}
2525
2526// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002527// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002529 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002530 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2531 EXPECT_TRUE(AddRecvStream(kSsrcY));
2532 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533}
2534
2535// Test that the local SSRC is the same on sending and receiving channels if the
2536// receive channel is created before the send channel.
2537TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002538 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002539 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002540 EXPECT_TRUE(
2541 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002542 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2543 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544}
2545
2546// Test that we can properly receive packets.
2547TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002548 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002549 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002551
Yves Gerey665174f2018-06-19 15:03:05 +02002552 EXPECT_TRUE(
2553 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002554}
2555
2556// Test that we can properly receive packets on multiple streams.
2557TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002558 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002559 const uint32_t ssrc1 = 1;
2560 const uint32_t ssrc2 = 2;
2561 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002562 EXPECT_TRUE(AddRecvStream(ssrc1));
2563 EXPECT_TRUE(AddRecvStream(ssrc2));
2564 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002566 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002567 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002568 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002569 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002570 }
mflodman3d7db262016-04-29 00:57:13 -07002571
2572 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2573 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2574 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2575
2576 EXPECT_EQ(s1.received_packets(), 0);
2577 EXPECT_EQ(s2.received_packets(), 0);
2578 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002579
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002580 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002581 EXPECT_EQ(s1.received_packets(), 0);
2582 EXPECT_EQ(s2.received_packets(), 0);
2583 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002584
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002585 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002586 EXPECT_EQ(s1.received_packets(), 1);
2587 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2588 EXPECT_EQ(s2.received_packets(), 0);
2589 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002590
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002591 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002592 EXPECT_EQ(s1.received_packets(), 1);
2593 EXPECT_EQ(s2.received_packets(), 1);
2594 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2595 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002596
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002597 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002598 EXPECT_EQ(s1.received_packets(), 1);
2599 EXPECT_EQ(s2.received_packets(), 1);
2600 EXPECT_EQ(s3.received_packets(), 1);
2601 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002602
mflodman3d7db262016-04-29 00:57:13 -07002603 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2604 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2605 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002606}
2607
solenberg2100c0b2017-03-01 11:29:29 -08002608// Test that receiving on an unsignaled stream works (a stream is created).
2609TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002610 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002611 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002612
solenberg7e63ef02015-11-20 00:19:43 -08002613 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002614
Mirko Bonadeif859e552018-05-30 15:31:29 +02002615 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002616 EXPECT_TRUE(
2617 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002618}
2619
Seth Hampson5897a6e2018-04-03 11:16:33 -07002620// Tests that when we add a stream without SSRCs, but contains a stream_id
2621// that it is stored and its stream id is later used when the first packet
2622// arrives to properly create a receive stream with a sync label.
2623TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2624 const char kSyncLabel[] = "sync_label";
2625 EXPECT_TRUE(SetupChannel());
2626 cricket::StreamParams unsignaled_stream;
2627 unsignaled_stream.set_stream_ids({kSyncLabel});
2628 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2629 // The stream shouldn't have been created at this point because it doesn't
2630 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002631 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002632
2633 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2634
Mirko Bonadeif859e552018-05-30 15:31:29 +02002635 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002636 EXPECT_TRUE(
2637 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2638 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2639
2640 // Removing the unsignaled stream clears the cached parameters. If a new
2641 // default unsignaled receive stream is created it will not have a sync group.
2642 channel_->RemoveRecvStream(0);
2643 channel_->RemoveRecvStream(kSsrc1);
2644
2645 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2646
Mirko Bonadeif859e552018-05-30 15:31:29 +02002647 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002648 EXPECT_TRUE(
2649 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2650 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2651}
2652
solenberg2100c0b2017-03-01 11:29:29 -08002653// Test that receiving N unsignaled stream works (streams will be created), and
2654// that packets are forwarded to them all.
2655TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002657 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002658 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2659
solenberg2100c0b2017-03-01 11:29:29 -08002660 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002661 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002662 rtc::SetBE32(&packet[8], ssrc);
2663 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002664
solenberg2100c0b2017-03-01 11:29:29 -08002665 // Verify we have one new stream for each loop iteration.
2666 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002667 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2668 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002669 }
mflodman3d7db262016-04-29 00:57:13 -07002670
solenberg2100c0b2017-03-01 11:29:29 -08002671 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002672 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002673 rtc::SetBE32(&packet[8], ssrc);
2674 DeliverPacket(packet, sizeof(packet));
2675
solenbergebb349d2017-03-13 05:46:15 -07002676 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002677 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2678 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2679 }
2680
2681 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2682 constexpr uint32_t kAnotherSsrc = 667;
2683 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002684 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002685
2686 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002687 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002688 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002689 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002690 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2691 EXPECT_EQ(2, streams[i]->received_packets());
2692 }
2693 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2694 EXPECT_EQ(1, streams[i]->received_packets());
2695 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002696 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002697}
2698
solenberg2100c0b2017-03-01 11:29:29 -08002699// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002700// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002701TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002703 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002704 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2705
2706 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002707 const uint32_t signaled_ssrc = 1;
2708 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002709 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002710 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002711 EXPECT_TRUE(
2712 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002713 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002714
2715 // Note that the first unknown SSRC cannot be 0, because we only support
2716 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002717 const uint32_t unsignaled_ssrc = 7011;
2718 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002719 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002720 EXPECT_TRUE(
2721 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002723
2724 DeliverPacket(packet, sizeof(packet));
2725 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2726
2727 rtc::SetBE32(&packet[8], signaled_ssrc);
2728 DeliverPacket(packet, sizeof(packet));
2729 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002730 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002731}
2732
solenberg4904fb62017-02-17 12:01:14 -08002733// Two tests to verify that adding a receive stream with the same SSRC as a
2734// previously added unsignaled stream will only recreate underlying stream
2735// objects if the stream parameters have changed.
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2737 EXPECT_TRUE(SetupChannel());
2738
2739 // Spawn unsignaled stream with SSRC=1.
2740 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002741 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002742 EXPECT_TRUE(
2743 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002744
2745 // Verify that the underlying stream object in Call is not recreated when a
2746 // stream with SSRC=1 is added.
2747 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002748 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002749 int audio_receive_stream_id = streams.front()->id();
2750 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002751 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002752 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2753}
2754
2755TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2756 EXPECT_TRUE(SetupChannel());
2757
2758 // Spawn unsignaled stream with SSRC=1.
2759 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002760 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002761 EXPECT_TRUE(
2762 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002763
2764 // Verify that the underlying stream object in Call *is* recreated when a
2765 // stream with SSRC=1 is added, and which has changed stream parameters.
2766 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002767 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002768 int audio_receive_stream_id = streams.front()->id();
2769 cricket::StreamParams stream_params;
2770 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002771 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002772 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002773 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002774 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2775}
2776
solenberg1ac56142015-10-13 03:58:19 -07002777// Test that AddRecvStream creates new stream.
2778TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002779 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002780 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781}
2782
2783// Test that after adding a recv stream, we do not decode more codecs than
2784// those previously passed into SetRecvCodecs.
2785TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002786 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002787 cricket::AudioRecvParameters parameters;
2788 parameters.codecs.push_back(kIsacCodec);
2789 parameters.codecs.push_back(kPcmuCodec);
2790 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002791 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002792 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2793 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2794 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795}
2796
2797// Test that we properly clean up any streams that were added, even if
2798// not explicitly removed.
2799TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002800 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002801 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002802 EXPECT_TRUE(AddRecvStream(1));
2803 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002804
Mirko Bonadeif859e552018-05-30 15:31:29 +02002805 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2806 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807 delete channel_;
2808 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002809 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2810 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811}
2812
wu@webrtc.org78187522013-10-07 23:32:02 +00002813TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002814 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002815 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002816}
2817
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002818TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002819 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002820 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002821 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002822}
2823
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002824// Test the InsertDtmf on default send stream as caller.
2825TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002826 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827}
2828
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002829// Test the InsertDtmf on default send stream as callee
2830TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002831 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002832}
2833
2834// Test the InsertDtmf on specified send stream as caller.
2835TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002836 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002837}
2838
2839// Test the InsertDtmf on specified send stream as callee.
2840TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002841 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002842}
2843
Johannes Kron9190b822018-10-29 11:22:05 +01002844// Test propagation of extmap allow mixed setting.
2845TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2846 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2847}
2848TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2849 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2850}
2851TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2852 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2853}
2854TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2855 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2856}
2857
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002859 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002860 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002861 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2862 .Times(9)
2863 .WillRepeatedly(Return(false));
2864 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2865 .Times(4)
2866 .WillRepeatedly(Return(false));
2867 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2868 .Times(2)
2869 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002870
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002871 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002872 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002873
solenberg246b8172015-12-08 09:50:23 -08002874 // Nothing set in AudioOptions, so everything should be as default.
2875 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002876 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002877 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002878 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002879 EXPECT_TRUE(IsTypingDetectionEnabled());
Jakob Ivarsson647d5e62019-03-15 10:37:31 +01002880 EXPECT_EQ(200u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002881 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
Sam Zackrissonba502232019-01-04 10:36:48 +01002883 // Turn typing detection off.
2884 send_parameters_.options.typing_detection = false;
2885 SetSendParameters(send_parameters_);
2886 EXPECT_FALSE(IsTypingDetectionEnabled());
2887
2888 // Leave typing detection unchanged, but non-default.
2889 send_parameters_.options.typing_detection = absl::nullopt;
2890 SetSendParameters(send_parameters_);
2891 EXPECT_FALSE(IsTypingDetectionEnabled());
2892
2893 // Turn typing detection on.
2894 send_parameters_.options.typing_detection = true;
2895 SetSendParameters(send_parameters_);
2896 EXPECT_TRUE(IsTypingDetectionEnabled());
2897
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002899 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002900 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002901 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902
2903 // Turn echo cancellation back on, with settings, and make sure
2904 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002905 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002906 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002907 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002909 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2910 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002911 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002912 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002913 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002914
2915 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002916 send_parameters_.options.delay_agnostic_aec = false;
2917 send_parameters_.options.extended_filter_aec = false;
2918 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002919 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002920 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002921
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002922 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002923 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002924 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002925 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002926
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927 // Turn off AGC
Oskar Sundbom78807582017-11-16 11:09:55 +01002928 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002929 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002930 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002931 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002932
2933 // Turn AGC back on
Oskar Sundbom78807582017-11-16 11:09:55 +01002934 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002935 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002936 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002937 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002939 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002940 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002941 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002942 send_parameters_.options.noise_suppression = false;
2943 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002944 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002945 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002946 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002947 EXPECT_FALSE(IsHighPassFilterEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002948 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949
solenberg1ac56142015-10-13 03:58:19 -07002950 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002951 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002952 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002953 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002954 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01002955 EXPECT_TRUE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002956}
2957
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002958TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002959 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002960 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2961 .Times(8)
2962 .WillRepeatedly(Return(false));
2963 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2964 .Times(8)
2965 .WillRepeatedly(Return(false));
2966 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2967 .Times(8)
2968 .WillRepeatedly(Return(false));
2969 EXPECT_CALL(adm_, RecordingIsInitialized())
2970 .Times(2)
2971 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002972 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2973 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peaha9cc40b2017-06-29 08:32:09 -07002974 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002975
kwiberg686a8ef2016-02-26 03:00:35 -08002976 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002977 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2978 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2979 cricket::AudioOptions(),
2980 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002981 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002982 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2983 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2984 cricket::AudioOptions(),
2985 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
2987 // Have to add a stream to make SetSend work.
2988 cricket::StreamParams stream1;
2989 stream1.ssrcs.push_back(1);
2990 channel1->AddSendStream(stream1);
2991 cricket::StreamParams stream2;
2992 stream2.ssrcs.push_back(2);
2993 channel2->AddSendStream(stream2);
2994
2995 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002996 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002997 parameters_options_all.options.echo_cancellation = true;
2998 parameters_options_all.options.auto_gain_control = true;
2999 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003002 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003003 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003004 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003005 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003006 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003007 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003008 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003009 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010
3011 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003012 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003013 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003014 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003015 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003016 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003017 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003018 VerifyGainControlEnabledCorrectly();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003019 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003020 expected_options.echo_cancellation = true;
3021 expected_options.auto_gain_control = true;
3022 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003023 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024
3025 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003026 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003027 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003028 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003029 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003030 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003031 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003032 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003033 expected_options.echo_cancellation = true;
3034 expected_options.auto_gain_control = false;
3035 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003036 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003037
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(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003040 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003041 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003042 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003044 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003045 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003046 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003047 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003048 VerifyGainControlEnabledCorrectly();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003049
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003050 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003051 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003052 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003053 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003054 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003055
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003056 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003057 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3058 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003059 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3060 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003061 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003062 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003063 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003064 EXPECT_TRUE(IsEchoCancellationEnabled());
Sam Zackrissonf0d1c032019-03-27 13:28:08 +01003065 EXPECT_FALSE(apm_config_.gain_controller1.enabled);
Oskar Sundbom78807582017-11-16 11:09:55 +01003066 expected_options.echo_cancellation = true;
3067 expected_options.auto_gain_control = false;
3068 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003069 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003070}
3071
wu@webrtc.orgde305012013-10-31 15:40:38 +00003072// This test verifies DSCP settings are properly applied on voice media channel.
3073TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003074 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003075 cricket::FakeNetworkInterface network_interface;
3076 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003077 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003078 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003079
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.
henrika919dc2e2017-10-12 14:24:55 +02003502 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003503 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003504 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003505 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003506 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003507 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003508 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003509 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003510 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003511 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003512 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3513 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3514 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003515 EXPECT_TRUE(channel != nullptr);
3516 delete channel;
solenbergff976312016-03-30 23:28:51 -07003517}
stefan658910c2015-09-03 05:48:32 -07003518
solenbergff976312016-03-30 23:28:51 -07003519// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003520TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3521 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003522 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003523 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003524 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003525 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003526 {
peaha9cc40b2017-06-29 08:32:09 -07003527 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003528 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003529 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003530 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003531 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003532 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003533 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003534 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003535 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003536 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3537 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3538 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003539 EXPECT_TRUE(channel != nullptr);
3540 delete channel;
3541 }
stefan658910c2015-09-03 05:48:32 -07003542}
3543
ossu20a4b3f2017-04-27 02:08:52 -07003544// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3545TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003546 // TODO(ossu): Why are the payload types of codecs with non-static payload
3547 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003548 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003549 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003550 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003551 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003552 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003553 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003554 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003555 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003556 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003557 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003558 (clockrate == 0 || codec.clockrate == clockrate);
3559 };
3560 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003561 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003562 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003563 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003564 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003565 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003566 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003567 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003568 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003569 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003570 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003571 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003572 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3573 // Remove these checks once both send and receive side assigns payload
3574 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003575 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003576 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003577 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003578 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003579 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003580 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003581 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003582 EXPECT_EQ(111, codec.id);
3583 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3584 EXPECT_EQ("10", codec.params.find("minptime")->second);
3585 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3586 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003587 }
3588 }
stefan658910c2015-09-03 05:48:32 -07003589}
3590
3591// Tests that VoE supports at least 32 channels
3592TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003593 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003594 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003595 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003596 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003597 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003598 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003599 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003600 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003601 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003602 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003603
3604 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003605 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003606 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003607 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3608 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3609 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003610 if (!channel)
3611 break;
stefan658910c2015-09-03 05:48:32 -07003612 channels[num_channels++] = channel;
3613 }
3614
Mirko Bonadeif859e552018-05-30 15:31:29 +02003615 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003616 EXPECT_EQ(expected, num_channels);
3617
3618 while (num_channels > 0) {
3619 delete channels[--num_channels];
3620 }
stefan658910c2015-09-03 05:48:32 -07003621}
3622
3623// Test that we set our preferred codecs properly.
3624TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003625 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3626 // - Check that our builtin codecs are usable by Channel.
3627 // - The codecs provided by the engine is usable by Channel.
3628 // It does not check that the codecs in the RecvParameters are actually
3629 // what we sent in - though it's probably reasonable to expect so, if
3630 // SetRecvParameters returns true.
3631 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003632 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003633 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003634 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003635 cricket::WebRtcVoiceEngine engine(
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003636 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003637 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003638 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003639 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003640 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003641 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003642 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003643 cricket::AudioOptions(),
3644 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003645 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003646 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003647 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003648}
ossu9def8002017-02-09 05:14:32 -08003649
3650TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3651 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003652 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3653 {48000, 2, 16000, 10000, 20000}};
3654 spec1.info.allow_comfort_noise = false;
3655 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003656 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003657 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3658 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003659 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003660 specs.push_back(webrtc::AudioCodecSpec{
3661 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3662 {16000, 1, 13300}});
3663 specs.push_back(
3664 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3665 specs.push_back(
3666 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003667
ossueb1fde42017-05-02 06:46:30 -07003668 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3669 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3670 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003671 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003672 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003673 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003674 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003675
peaha9cc40b2017-06-29 08:32:09 -07003676 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003677 webrtc::AudioProcessingBuilder().Create();
Amit Hilbuche27ccf92019-03-26 17:36:53 +00003678 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003679 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003680 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003681 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003682 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003683
3684 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3685 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003686 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3687 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3688 if (codecs.size() > index)
3689 return codecs[index];
3690 return missing_codec;
3691 };
ossu9def8002017-02-09 05:14:32 -08003692
3693 // Ensure the general codecs are generated first and in order.
3694 for (size_t i = 0; i != specs.size(); ++i) {
3695 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3696 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3697 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3698 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3699 }
3700
3701 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003702 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003703 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3704 for (size_t i = 0; i != codecs.size(); ++i) {
3705 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003706 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003707 codec.clockrate == format.clockrate_hz &&
3708 codec.channels == format.num_channels) {
3709 return rtc::checked_cast<int>(i);
3710 }
3711 }
3712 return -1;
3713 };
ossu9def8002017-02-09 05:14:32 -08003714
3715 // Ensure all supplementary codecs are generated last. Their internal ordering
3716 // is not important.
3717 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3718 const int num_specs = static_cast<int>(specs.size());
3719 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3720 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3721 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3722 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3723 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3724 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3725 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3726}