blob: 36c0923af1abe1f2c6cf805e12ec601164f421d9 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010039using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010046using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020047
solenberg418b7d32017-06-13 00:38:27 -070048constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070049
deadbeef67cf2c12016-04-13 10:07:16 -070050const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
51const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070052const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
54const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
56const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020057const cricket::AudioCodec kTelephoneEventCodec1(106,
58 "telephone-event",
59 8000,
60 0,
61 1);
62const cricket::AudioCodec kTelephoneEventCodec2(107,
63 "telephone-event",
64 32000,
65 0,
66 1);
solenberg2779bab2016-11-17 04:45:19 -080067
solenberg2100c0b2017-03-01 11:29:29 -080068const uint32_t kSsrc0 = 0;
69const uint32_t kSsrc1 = 1;
70const uint32_t kSsrcX = 0x99;
71const uint32_t kSsrcY = 0x17;
72const uint32_t kSsrcZ = 0x42;
73const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020074const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075
solenberg971cab02016-06-14 10:02:41 -070076constexpr int kRtpHistoryMs = 5000;
77
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010078constexpr webrtc::GainControl::Mode kDefaultAgcMode =
79#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
80 webrtc::GainControl::kFixedDigital;
81#else
82 webrtc::GainControl::kAdaptiveAnalog;
83#endif
84
85constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
86 webrtc::NoiseSuppression::kHigh;
87
solenberg9a5f032222017-03-15 06:14:12 -070088void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
89 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010090
91 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010092 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010093 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010094 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070095#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020096 EXPECT_CALL(
97 *adm, SetPlayoutDevice(
98 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
99 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
100 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700101#else
102 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
103#endif // #if defined(WEBRTC_WIN)
104 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
105 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
106 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100107#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200108 EXPECT_CALL(
109 *adm, SetRecordingDevice(
110 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
111 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
112 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113#else
114 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
115#endif // #if defined(WEBRTC_WIN)
116 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
118 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700119 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100122
123 // Teardown.
124 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
125 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
127 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200128 EXPECT_CALL(*adm, Release())
129 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100130 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700131}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200132} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133
solenbergff976312016-03-30 23:28:51 -0700134// Tests that our stub library "works".
135TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700136 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700137 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700138 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
139 new rtc::RefCountedObject<
140 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700141 webrtc::AudioProcessing::Config apm_config;
142 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
143 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700144 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700146 {
ossuc54071d2016-08-17 02:45:41 -0700147 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700148 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100149 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700150 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700151 }
solenbergff976312016-03-30 23:28:51 -0700152}
153
deadbeef884f5852016-01-15 09:20:04 -0800154class FakeAudioSink : public webrtc::AudioSinkInterface {
155 public:
156 void OnData(const Data& audio) override {}
157};
158
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800159class FakeAudioSource : public cricket::AudioSource {
160 void SetSink(Sink* sink) override {}
161};
162
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163class WebRtcVoiceEngineTestFake : public testing::Test {
164 public:
stefanba4c0e42016-02-04 04:12:24 -0800165 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
166
167 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700168 : apm_(new rtc::RefCountedObject<
169 StrictMock<webrtc::test::MockAudioProcessing>>()),
170 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700171 apm_ns_(*apm_->noise_suppression()),
172 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100173 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700174 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800175 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700176 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800177 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700178 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
179 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700180 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800182 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100183 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800184 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100185 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
186 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800189 // Init does not overwrite default AGC config.
190 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
191 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
192 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
194 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700195 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800196 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700197 // factories. Those tests should probably be moved elsewhere.
198 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
199 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100200 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100201 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200207 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 }
solenberg8189b022016-06-14 12:13:00 -0700210
solenbergff976312016-03-30 23:28:51 -0700211 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700212 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700213 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700214 cricket::AudioOptions(),
215 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupRecvStream() {
220 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700221 return false;
222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200227 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
228 }
229
230 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700231 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000232 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
Florent Castellidacec712018-05-24 16:24:21 +0200234 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800235 return false;
236 }
peaha9cc40b2017-06-29 08:32:09 -0700237 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800238 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 }
solenberg8189b022016-06-14 12:13:00 -0700240
241 bool AddRecvStream(uint32_t ssrc) {
242 EXPECT_TRUE(channel_);
243 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
244 }
245
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700247 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700248 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800249 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
250 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700251 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800252 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000253 }
solenberg8189b022016-06-14 12:13:00 -0700254
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700256 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000257 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 }
solenberg8189b022016-06-14 12:13:00 -0700259
Yves Gerey665174f2018-06-19 15:03:05 +0200260 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100262 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
263 const auto* send_stream = call_.GetAudioSendStream(ssrc);
264 EXPECT_TRUE(send_stream);
265 return *send_stream;
266 }
267
deadbeef884f5852016-01-15 09:20:04 -0800268 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
269 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
270 EXPECT_TRUE(recv_stream);
271 return *recv_stream;
272 }
273
solenberg3a941542015-11-16 07:34:50 -0800274 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800275 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800276 }
277
solenberg7add0582015-11-20 09:59:34 -0800278 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800279 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800280 }
281
solenberg059fb442016-10-26 05:12:24 -0700282 void SetSend(bool enable) {
283 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700284 if (enable) {
285 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700289 }
solenberg059fb442016-10-26 05:12:24 -0700290 channel_->SetSend(enable);
291 }
292
293 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700294 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700295 ASSERT_TRUE(channel_);
296 EXPECT_TRUE(channel_->SetSendParameters(params));
297 }
298
Yves Gerey665174f2018-06-19 15:03:05 +0200299 void SetAudioSend(uint32_t ssrc,
300 bool enable,
301 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700302 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700303 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700304 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700305 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700306 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700307 }
308 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700309 }
310
Yves Gerey665174f2018-06-19 15:03:05 +0200311 void TestInsertDtmf(uint32_t ssrc,
312 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800313 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700314 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700316 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200318 EXPECT_TRUE(
319 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
324 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800327 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330
331 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700332 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200334 EXPECT_TRUE(
335 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000336 }
337
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 // Test send.
342 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800343 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800345 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800346 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800347 EXPECT_EQ(codec.id, telephone_event.payload_type);
348 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(2, telephone_event.event_code);
350 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 }
352
353 // Test that send bandwidth is set correctly.
354 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000355 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
356 // |expected_result| is the expected result from SetMaxSendBandwidth().
357 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700358 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
359 int max_bitrate,
360 bool expected_result,
361 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200362 cricket::AudioSendParameters parameters;
363 parameters.codecs.push_back(codec);
364 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700365 if (expected_result) {
366 SetSendParameters(parameters);
367 } else {
368 EXPECT_FALSE(channel_->SetSendParameters(parameters));
369 }
solenberg2100c0b2017-03-01 11:29:29 -0800370 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371 }
372
skvlade0d46372016-04-07 22:59:22 -0700373 // Sets the per-stream maximum bitrate limit for the specified SSRC.
374 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700375 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700376 EXPECT_EQ(1UL, parameters.encodings.size());
377
Oskar Sundbom78807582017-11-16 11:09:55 +0100378 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800379 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700380 }
381
solenberg059fb442016-10-26 05:12:24 -0700382 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700383 cricket::AudioSendParameters send_parameters;
384 send_parameters.codecs.push_back(codec);
385 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700386 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700387 }
388
ossu20a4b3f2017-04-27 02:08:52 -0700389 void CheckSendCodecBitrate(int32_t ssrc,
390 const char expected_name[],
391 int expected_bitrate) {
392 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
393 EXPECT_EQ(expected_name, spec->format.name);
394 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700395 }
396
Danil Chapovalov00c71832018-06-15 15:58:38 +0200397 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700398 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700399 }
400
Danil Chapovalov00c71832018-06-15 15:58:38 +0200401 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
402 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700403 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
404 }
405
skvlade0d46372016-04-07 22:59:22 -0700406 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
407 int global_max,
408 int stream_max,
409 bool expected_result,
410 int expected_codec_bitrate) {
411 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800412 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700413
414 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700415 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800416 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700417
418 // Verify that reading back the parameters gives results
419 // consistent with the Set() result.
420 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800421 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700422 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
423 EXPECT_EQ(expected_result ? stream_max : -1,
424 resulting_parameters.encodings[0].max_bitrate_bps);
425
426 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800427 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700428 }
429
stefan13f1a0a2016-11-30 07:22:58 -0800430 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
431 int expected_min_bitrate_bps,
432 const char* start_bitrate_kbps,
433 int expected_start_bitrate_bps,
434 const char* max_bitrate_kbps,
435 int expected_max_bitrate_bps) {
436 EXPECT_TRUE(SetupSendStream());
437 auto& codecs = send_parameters_.codecs;
438 codecs.clear();
439 codecs.push_back(kOpusCodec);
440 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
441 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
442 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100443 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
444 SetSdpBitrateParameters(
445 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
446 expected_min_bitrate_bps),
447 Field(&BitrateConstraints::start_bitrate_bps,
448 expected_start_bitrate_bps),
449 Field(&BitrateConstraints::max_bitrate_bps,
450 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800451
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100452 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800453 }
454
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000455 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700456 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800459 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000460
461 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700462 send_parameters_.extensions.push_back(
463 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700464 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800465 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000466
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000467 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200468 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700469 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800470 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 // Ensure extension is set properly.
473 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700474 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700475 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000479
solenberg7add0582015-11-20 09:59:34 -0800480 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200481 EXPECT_TRUE(
482 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
484 call_.GetAudioSendStream(kSsrcY));
485 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
486 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
487 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000488
489 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200490 send_parameters_.codecs.push_back(kPcmuCodec);
491 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700492 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000495 }
496
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000497 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700498 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000502
503 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700504 recv_parameters_.extensions.push_back(
505 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800506 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800507 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000508
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000509 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800510 recv_parameters_.extensions.clear();
511 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800512 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000514 // Ensure extension is set properly.
515 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700516 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800517 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000521
solenberg7add0582015-11-20 09:59:34 -0800522 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800523 EXPECT_TRUE(AddRecvStream(kSsrcY));
524 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
525 call_.GetAudioReceiveStream(kSsrcY));
526 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
527 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
528 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000529
530 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800531 recv_parameters_.extensions.clear();
532 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800533 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
534 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000535 }
536
solenberg85a04962015-10-27 03:35:21 -0700537 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
538 webrtc::AudioSendStream::Stats stats;
539 stats.local_ssrc = 12;
540 stats.bytes_sent = 345;
541 stats.packets_sent = 678;
542 stats.packets_lost = 9012;
543 stats.fraction_lost = 34.56f;
544 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100545 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700546 stats.ext_seqnum = 789;
547 stats.jitter_ms = 12;
548 stats.rtt_ms = 345;
549 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100550 stats.apm_statistics.delay_median_ms = 234;
551 stats.apm_statistics.delay_standard_deviation_ms = 567;
552 stats.apm_statistics.echo_return_loss = 890;
553 stats.apm_statistics.echo_return_loss_enhancement = 1234;
554 stats.apm_statistics.residual_echo_likelihood = 0.432f;
555 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100556 stats.ana_statistics.bitrate_action_counter = 321;
557 stats.ana_statistics.channel_action_counter = 432;
558 stats.ana_statistics.dtx_action_counter = 543;
559 stats.ana_statistics.fec_action_counter = 654;
560 stats.ana_statistics.frame_length_increase_counter = 765;
561 stats.ana_statistics.frame_length_decrease_counter = 876;
562 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700563 stats.typing_noise_detected = true;
564 return stats;
565 }
566 void SetAudioSendStreamStats() {
567 for (auto* s : call_.GetAudioSendStreams()) {
568 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200569 }
solenberg85a04962015-10-27 03:35:21 -0700570 }
solenberg566ef242015-11-06 15:34:49 -0800571 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
572 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700573 const auto stats = GetAudioSendStreamStats();
574 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
575 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
576 EXPECT_EQ(info.packets_sent, stats.packets_sent);
577 EXPECT_EQ(info.packets_lost, stats.packets_lost);
578 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
579 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800580 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700581 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
582 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
583 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
584 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100585 EXPECT_EQ(info.apm_statistics.delay_median_ms,
586 stats.apm_statistics.delay_median_ms);
587 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
588 stats.apm_statistics.delay_standard_deviation_ms);
589 EXPECT_EQ(info.apm_statistics.echo_return_loss,
590 stats.apm_statistics.echo_return_loss);
591 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
592 stats.apm_statistics.echo_return_loss_enhancement);
593 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
594 stats.apm_statistics.residual_echo_likelihood);
595 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
596 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700597 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
598 stats.ana_statistics.bitrate_action_counter);
599 EXPECT_EQ(info.ana_statistics.channel_action_counter,
600 stats.ana_statistics.channel_action_counter);
601 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
602 stats.ana_statistics.dtx_action_counter);
603 EXPECT_EQ(info.ana_statistics.fec_action_counter,
604 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700605 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
606 stats.ana_statistics.frame_length_increase_counter);
607 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
608 stats.ana_statistics.frame_length_decrease_counter);
609 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
610 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800611 EXPECT_EQ(info.typing_noise_detected,
612 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700613 }
614
615 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
616 webrtc::AudioReceiveStream::Stats stats;
617 stats.remote_ssrc = 123;
618 stats.bytes_rcvd = 456;
619 stats.packets_rcvd = 768;
620 stats.packets_lost = 101;
621 stats.fraction_lost = 23.45f;
622 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100623 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700624 stats.ext_seqnum = 678;
625 stats.jitter_ms = 901;
626 stats.jitter_buffer_ms = 234;
627 stats.jitter_buffer_preferred_ms = 567;
628 stats.delay_estimate_ms = 890;
629 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700630 stats.total_samples_received = 5678901;
631 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200632 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200633 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700634 stats.expand_rate = 5.67f;
635 stats.speech_expand_rate = 8.90f;
636 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200637 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700638 stats.accelerate_rate = 4.56f;
639 stats.preemptive_expand_rate = 7.89f;
640 stats.decoding_calls_to_silence_generator = 12;
641 stats.decoding_calls_to_neteq = 345;
642 stats.decoding_normal = 67890;
643 stats.decoding_plc = 1234;
644 stats.decoding_cng = 5678;
645 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700646 stats.decoding_muted_output = 3456;
647 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200648 return stats;
649 }
650 void SetAudioReceiveStreamStats() {
651 for (auto* s : call_.GetAudioReceiveStreams()) {
652 s->SetStats(GetAudioReceiveStreamStats());
653 }
654 }
655 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700656 const auto stats = GetAudioReceiveStreamStats();
657 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
658 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200659 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
660 stats.packets_rcvd);
661 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
662 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700663 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
664 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800665 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200666 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
667 stats.ext_seqnum);
668 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
669 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
670 stats.jitter_buffer_ms);
671 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700672 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200673 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
674 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700675 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700676 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
677 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200678 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200679 EXPECT_EQ(info.jitter_buffer_delay_seconds,
680 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700681 EXPECT_EQ(info.expand_rate, stats.expand_rate);
682 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
683 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200684 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700685 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
686 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200687 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700688 stats.decoding_calls_to_silence_generator);
689 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
690 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
691 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
692 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
693 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700694 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700695 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200696 }
hbos1acfbd22016-11-17 23:43:29 -0800697 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
698 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
699 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
700 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
701 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
702 codec.ToCodecParameters());
703 }
704 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
705 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
706 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
707 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
708 codec.ToCodecParameters());
709 }
710 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200711
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200712 bool IsEchoCancellationEnabled() {
713 return engine_->GetApmConfigForTest().echo_canceller.enabled;
714 }
715
peah8271d042016-11-22 07:24:52 -0800716 bool IsHighPassFilterEnabled() {
717 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
718 }
719
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700721 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700722 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800723 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800724 webrtc::test::MockNoiseSuppression& apm_ns_;
725 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200726 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700727 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700728 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200729 cricket::AudioSendParameters send_parameters_;
730 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800731 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700732 webrtc::AudioProcessing::Config apm_config_;
733
stefanba4c0e42016-02-04 04:12:24 -0800734 private:
735 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736};
737
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738// Tests that we can create and destroy a channel.
739TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700740 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741}
742
solenberg31fec402016-05-06 02:13:12 -0700743// Test that we can add a send stream and that it has the correct defaults.
744TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
745 EXPECT_TRUE(SetupChannel());
746 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800747 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
748 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
749 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700750 EXPECT_EQ("", config.rtp.c_name);
751 EXPECT_EQ(0u, config.rtp.extensions.size());
752 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
753 config.send_transport);
754}
755
756// Test that we can add a receive stream and that it has the correct defaults.
757TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
758 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800759 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700760 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800761 GetRecvStreamConfig(kSsrcX);
762 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700763 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
764 EXPECT_FALSE(config.rtp.transport_cc);
765 EXPECT_EQ(0u, config.rtp.extensions.size());
766 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
767 config.rtcp_send_transport);
768 EXPECT_EQ("", config.sync_group);
769}
770
stefanba4c0e42016-02-04 04:12:24 -0800771TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700772 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800773 bool opus_found = false;
774 for (cricket::AudioCodec codec : codecs) {
775 if (codec.name == "opus") {
776 EXPECT_TRUE(HasTransportCc(codec));
777 opus_found = true;
778 }
779 }
780 EXPECT_TRUE(opus_found);
781}
782
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783// Test that we set our inbound codecs properly, including changing PT.
784TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700785 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200786 cricket::AudioRecvParameters parameters;
787 parameters.codecs.push_back(kIsacCodec);
788 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800789 parameters.codecs.push_back(kTelephoneEventCodec1);
790 parameters.codecs.push_back(kTelephoneEventCodec2);
791 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200792 parameters.codecs[2].id = 126;
793 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800794 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700795 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
796 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
797 {{0, {"PCMU", 8000, 1}},
798 {106, {"ISAC", 16000, 1}},
799 {126, {"telephone-event", 8000, 1}},
800 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801}
802
803// Test that we fail to set an unknown inbound codec.
804TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700805 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200806 cricket::AudioRecvParameters parameters;
807 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700808 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200809 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810}
811
812// Test that we fail if we have duplicate types in the inbound list.
813TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700814 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200815 cricket::AudioRecvParameters parameters;
816 parameters.codecs.push_back(kIsacCodec);
817 parameters.codecs.push_back(kCn16000Codec);
818 parameters.codecs[1].id = kIsacCodec.id;
819 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820}
821
822// Test that we can decode OPUS without stereo parameters.
823TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700824 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200825 cricket::AudioRecvParameters parameters;
826 parameters.codecs.push_back(kIsacCodec);
827 parameters.codecs.push_back(kPcmuCodec);
828 parameters.codecs.push_back(kOpusCodec);
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 {103, {"ISAC", 16000, 1}},
835 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836}
837
838// Test that we can decode OPUS with stereo = 0.
839TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700840 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 cricket::AudioRecvParameters parameters;
842 parameters.codecs.push_back(kIsacCodec);
843 parameters.codecs.push_back(kPcmuCodec);
844 parameters.codecs.push_back(kOpusCodec);
845 parameters.codecs[2].params["stereo"] = "0";
846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800847 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700848 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
849 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
850 {{0, {"PCMU", 8000, 1}},
851 {103, {"ISAC", 16000, 1}},
852 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that we can decode OPUS with stereo = 1.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kPcmuCodec);
861 parameters.codecs.push_back(kOpusCodec);
862 parameters.codecs[2].params["stereo"] = "1";
863 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800864 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700865 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
866 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
867 {{0, {"PCMU", 8000, 1}},
868 {103, {"ISAC", 16000, 1}},
869 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870}
871
872// Test that changes to recv codecs are applied to all streams.
873TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700874 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200875 cricket::AudioRecvParameters parameters;
876 parameters.codecs.push_back(kIsacCodec);
877 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800878 parameters.codecs.push_back(kTelephoneEventCodec1);
879 parameters.codecs.push_back(kTelephoneEventCodec2);
880 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 parameters.codecs[2].id = 126;
882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700883 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
884 EXPECT_TRUE(AddRecvStream(ssrc));
885 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
886 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
887 {{0, {"PCMU", 8000, 1}},
888 {106, {"ISAC", 16000, 1}},
889 {126, {"telephone-event", 8000, 1}},
890 {107, {"telephone-event", 32000, 1}}})));
891 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700895 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200896 cricket::AudioRecvParameters parameters;
897 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800898 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
solenberg2100c0b2017-03-01 11:29:29 -0800901 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200902 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800903 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904}
905
906// Test that we can apply the same set of codecs again while playing.
907TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700908 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200909 cricket::AudioRecvParameters parameters;
910 parameters.codecs.push_back(kIsacCodec);
911 parameters.codecs.push_back(kCn16000Codec);
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700913 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
deadbeefcb383672017-04-26 16:28:42 -0700916 // Remapping a payload type to a different codec should fail.
917 parameters.codecs[0] = kOpusCodec;
918 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200919 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800920 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921}
922
923// Test that we can add a codec while playing.
924TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700925 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
928 parameters.codecs.push_back(kCn16000Codec);
929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700930 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200932 parameters.codecs.push_back(kOpusCodec);
933 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800934 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935}
936
deadbeefcb383672017-04-26 16:28:42 -0700937// Test that we accept adding the same codec with a different payload type.
938// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
939TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
940 EXPECT_TRUE(SetupRecvStream());
941 cricket::AudioRecvParameters parameters;
942 parameters.codecs.push_back(kIsacCodec);
943 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
944
945 ++parameters.codecs[0].id;
946 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
947}
948
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700950 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000952 // Test that when autobw is enabled, bitrate is kept as the default
953 // value. autobw is enabled for the following tests because the target
954 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955
956 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700957 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
959 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
ossu20a4b3f2017-04-27 02:08:52 -0700962 // opus, default bitrate == 32000 in mono.
963 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700967 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700970 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
971 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700972 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700975 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
976 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
977 // Rates above the max (510000) should be capped.
978 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979}
980
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000981TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700982 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983
984 // Test that we can only set a maximum bitrate for a fixed-rate codec
985 // if it's bigger than the fixed rate.
986
987 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700988 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
989 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
991 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000995}
996
997TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200999 const int kDesiredBitrate = 128000;
1000 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001001 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001002 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001003 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001004
Yves Gerey665174f2018-06-19 15:03:05 +02001005 EXPECT_TRUE(
1006 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001007
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001009}
1010
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011// Test that bitrate cannot be set for CBR codecs.
1012// Bitrate is ignored if it is higher than the fixed bitrate.
1013// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001014TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001015 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
1017 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001018 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001019 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001020
1021 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001022 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001023 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001024
1025 send_parameters_.max_bandwidth_bps = 128;
1026 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001027 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028}
1029
skvlade0d46372016-04-07 22:59:22 -07001030// Test that the per-stream bitrate limit and the global
1031// bitrate limit both apply.
1032TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1033 EXPECT_TRUE(SetupSendStream());
1034
ossu20a4b3f2017-04-27 02:08:52 -07001035 // opus, default bitrate == 32000.
1036 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001037 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1038 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1039 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1040
1041 // CBR codecs allow both maximums to exceed the bitrate.
1042 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1043 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1044 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1045 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1046
1047 // CBR codecs don't allow per stream maximums to be too low.
1048 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1049 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1050}
1051
1052// Test that an attempt to set RtpParameters for a stream that does not exist
1053// fails.
1054TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1055 EXPECT_TRUE(SetupChannel());
1056 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001057 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001058 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001059
1060 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001061 EXPECT_FALSE(
1062 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001063}
1064
1065TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001066 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001067 // This test verifies that setting RtpParameters succeeds only if
1068 // the structure contains exactly one encoding.
1069 // TODO(skvlad): Update this test when we start supporting setting parameters
1070 // for each encoding individually.
1071
1072 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001074 // Two or more encodings should result in failure.
1075 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001076 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001077 // Zero encodings should also fail.
1078 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001079 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001080}
1081
1082// Changing the SSRC through RtpParameters is not allowed.
1083TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1084 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001085 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001086 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001087 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001088}
1089
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001090// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001091// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1093 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001094 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001095 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001096 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001097 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098 ASSERT_EQ(1u, parameters.encodings.size());
1099 ASSERT_TRUE(parameters.encodings[0].active);
1100 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001101 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001102 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001103
1104 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001105 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001106 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001107 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001108 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001109 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001110}
1111
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112// Test that SetRtpSendParameters configures the correct encoding channel for
1113// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001114TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1115 SetupForMultiSendStream();
1116 // Create send streams.
1117 for (uint32_t ssrc : kSsrcs4) {
1118 EXPECT_TRUE(
1119 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1120 }
1121 // Configure one stream to be limited by the stream config, another to be
1122 // limited by the global max, and the third one with no per-stream limit
1123 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001124 SetGlobalMaxBitrate(kOpusCodec, 32000);
1125 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1128
ossu20a4b3f2017-04-27 02:08:52 -07001129 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1130 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1131 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001132
1133 // Remove the global cap; the streams should switch to their respective
1134 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001135 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001136 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1137 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1138 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001139}
1140
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001141// Test that GetRtpSendParameters returns the currently configured codecs.
1142TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143 EXPECT_TRUE(SetupSendStream());
1144 cricket::AudioSendParameters parameters;
1145 parameters.codecs.push_back(kIsacCodec);
1146 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001147 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148
solenberg2100c0b2017-03-01 11:29:29 -08001149 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1152 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001153}
1154
Florent Castellidacec712018-05-24 16:24:21 +02001155// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1156TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1157 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1158 params.cname = "rtcpcname";
1159 EXPECT_TRUE(SetupSendStream(params));
1160
1161 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1162 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1163}
1164
Florent Castelliabe301f2018-06-12 18:33:49 +02001165TEST_F(WebRtcVoiceEngineTestFake,
1166 DetectRtpSendParameterHeaderExtensionsChange) {
1167 EXPECT_TRUE(SetupSendStream());
1168
1169 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1170 rtp_parameters.header_extensions.emplace_back();
1171
1172 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1173
1174 webrtc::RTCError result =
1175 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1176 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1177}
1178
deadbeefcb443432016-12-12 11:12:36 -08001179// Test that GetRtpSendParameters returns an SSRC.
1180TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1181 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001182 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001183 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001184 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001185}
1186
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001187// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001188TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001189 EXPECT_TRUE(SetupSendStream());
1190 cricket::AudioSendParameters parameters;
1191 parameters.codecs.push_back(kIsacCodec);
1192 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001193 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001194
solenberg2100c0b2017-03-01 11:29:29 -08001195 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001196
1197 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001198 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001199
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001200 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001201 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1202 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001203}
1204
minyuececec102017-03-27 13:04:25 -07001205// Test that max_bitrate_bps in send stream config gets updated correctly when
1206// SetRtpSendParameters is called.
1207TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1208 webrtc::test::ScopedFieldTrials override_field_trials(
1209 "WebRTC-Audio-SendSideBwe/Enabled/");
1210 EXPECT_TRUE(SetupSendStream());
1211 cricket::AudioSendParameters send_parameters;
1212 send_parameters.codecs.push_back(kOpusCodec);
1213 SetSendParameters(send_parameters);
1214
1215 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1216 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1217 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1218
1219 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001220 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001221 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001222
1223 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1224 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1225}
1226
Seth Hampson24722b32017-12-22 09:36:42 -08001227// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1228// a value <= 0, setting the parameters returns false.
1229TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1230 EXPECT_TRUE(SetupSendStream());
1231 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1232 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1233 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1234 rtp_parameters.encodings[0].bitrate_priority);
1235
1236 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001237 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001238 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001239 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001240}
1241
1242// Test that the bitrate_priority in the send stream config gets updated when
1243// SetRtpSendParameters is set for the VoiceMediaChannel.
1244TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1245 EXPECT_TRUE(SetupSendStream());
1246 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1247
1248 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1249 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1250 rtp_parameters.encodings[0].bitrate_priority);
1251 double new_bitrate_priority = 2.0;
1252 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001253 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001254
1255 // The priority should get set for both the audio channel's rtp parameters
1256 // and the audio send stream's audio config.
1257 EXPECT_EQ(
1258 new_bitrate_priority,
1259 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1260 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1261}
1262
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001263// Test that GetRtpReceiveParameters returns the currently configured codecs.
1264TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1265 EXPECT_TRUE(SetupRecvStream());
1266 cricket::AudioRecvParameters parameters;
1267 parameters.codecs.push_back(kIsacCodec);
1268 parameters.codecs.push_back(kPcmuCodec);
1269 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1270
1271 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001272 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001273 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1274 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1275 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1276}
1277
deadbeefcb443432016-12-12 11:12:36 -08001278// Test that GetRtpReceiveParameters returns an SSRC.
1279TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1280 EXPECT_TRUE(SetupRecvStream());
1281 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001282 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001283 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001284 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001285}
1286
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001287// Test that if we set/get parameters multiple times, we get the same results.
1288TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1289 EXPECT_TRUE(SetupRecvStream());
1290 cricket::AudioRecvParameters parameters;
1291 parameters.codecs.push_back(kIsacCodec);
1292 parameters.codecs.push_back(kPcmuCodec);
1293 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1294
1295 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001296 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001297
1298 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001299 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001300
1301 // ... And this shouldn't change the params returned by
1302 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001303 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1304 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001305}
1306
deadbeef3bc15102017-04-20 19:25:07 -07001307// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1308// aren't signaled. It should return an empty "RtpEncodingParameters" when
1309// configured to receive an unsignaled stream and no packets have been received
1310// yet, and start returning the SSRC once a packet has been received.
1311TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1312 ASSERT_TRUE(SetupChannel());
1313 // Call necessary methods to configure receiving a default stream as
1314 // soon as it arrives.
1315 cricket::AudioRecvParameters parameters;
1316 parameters.codecs.push_back(kIsacCodec);
1317 parameters.codecs.push_back(kPcmuCodec);
1318 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1319
1320 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1321 // stream. Should return nothing.
1322 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1323
1324 // Set a sink for an unsignaled stream.
1325 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1326 // Value of "0" means "unsignaled stream".
1327 channel_->SetRawAudioSink(0, std::move(fake_sink));
1328
1329 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1330 // in this method means "unsignaled stream".
1331 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1332 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1333 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1334
1335 // Receive PCMU packet (SSRC=1).
1336 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1337
1338 // The |ssrc| member should still be unset.
1339 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1340 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1341 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1342}
1343
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344// Test that we apply codecs properly.
1345TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001346 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001347 cricket::AudioSendParameters parameters;
1348 parameters.codecs.push_back(kIsacCodec);
1349 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001350 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001352 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001353 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001354 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1355 EXPECT_EQ(96, send_codec_spec.payload_type);
1356 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1357 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1358 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001359 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001360 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361}
1362
ossu20a4b3f2017-04-27 02:08:52 -07001363// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1364// AudioSendStream.
1365TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kIsacCodec);
1369 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001370 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 parameters.codecs[0].id = 96;
1372 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001373 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001374 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001375 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001376 // Calling SetSendCodec again with same codec which is already set.
1377 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001378 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001379 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001380}
1381
ossu20a4b3f2017-04-27 02:08:52 -07001382// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1383// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001384
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001385// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001387 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 cricket::AudioSendParameters parameters;
1389 parameters.codecs.push_back(kOpusCodec);
1390 parameters.codecs[0].bitrate = 0;
1391 parameters.codecs[0].clockrate = 50000;
1392 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393}
1394
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001395// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].bitrate = 0;
1401 parameters.codecs[0].channels = 0;
1402 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403}
1404
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001405// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001407 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001408 cricket::AudioSendParameters parameters;
1409 parameters.codecs.push_back(kOpusCodec);
1410 parameters.codecs[0].bitrate = 0;
1411 parameters.codecs[0].channels = 0;
1412 parameters.codecs[0].params["stereo"] = "1";
1413 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414}
1415
1416// Test that if channel is 1 for opus and there's no stereo, we fail.
1417TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001418 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 cricket::AudioSendParameters parameters;
1420 parameters.codecs.push_back(kOpusCodec);
1421 parameters.codecs[0].bitrate = 0;
1422 parameters.codecs[0].channels = 1;
1423 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424}
1425
1426// Test that if channel is 1 for opus and stereo=0, we fail.
1427TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001428 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 cricket::AudioSendParameters parameters;
1430 parameters.codecs.push_back(kOpusCodec);
1431 parameters.codecs[0].bitrate = 0;
1432 parameters.codecs[0].channels = 1;
1433 parameters.codecs[0].params["stereo"] = "0";
1434 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435}
1436
1437// Test that if channel is 1 for opus and stereo=1, we fail.
1438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001439 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 cricket::AudioSendParameters parameters;
1441 parameters.codecs.push_back(kOpusCodec);
1442 parameters.codecs[0].bitrate = 0;
1443 parameters.codecs[0].channels = 1;
1444 parameters.codecs[0].params["stereo"] = "1";
1445 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
ossu20a4b3f2017-04-27 02:08:52 -07001448// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001454 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001455 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456}
1457
ossu20a4b3f2017-04-27 02:08:52 -07001458// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001460 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001461 cricket::AudioSendParameters parameters;
1462 parameters.codecs.push_back(kOpusCodec);
1463 parameters.codecs[0].bitrate = 0;
1464 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001465 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001466 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467}
1468
ossu20a4b3f2017-04-27 02:08:52 -07001469// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001475 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001478 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001479
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001480 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001481 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001482 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001483}
1484
ossu20a4b3f2017-04-27 02:08:52 -07001485// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001487 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001488 cricket::AudioSendParameters parameters;
1489 parameters.codecs.push_back(kOpusCodec);
1490 parameters.codecs[0].bitrate = 0;
1491 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001492 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001493 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494}
1495
ossu20a4b3f2017-04-27 02:08:52 -07001496// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001502 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001504 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001505 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001506
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001507 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001508 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001509 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001510}
1511
ossu20a4b3f2017-04-27 02:08:52 -07001512// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001514 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001515 cricket::AudioSendParameters parameters;
1516 parameters.codecs.push_back(kOpusCodec);
1517 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001518 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001519 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1520 EXPECT_EQ(111, spec.payload_type);
1521 EXPECT_EQ(96000, spec.target_bitrate_bps);
1522 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001523 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001524 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001525}
1526
ossu20a4b3f2017-04-27 02:08:52 -07001527// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
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].bitrate = 30000;
1533 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001534 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001535 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001536}
1537
ossu20a4b3f2017-04-27 02:08:52 -07001538// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001540 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 cricket::AudioSendParameters parameters;
1542 parameters.codecs.push_back(kOpusCodec);
1543 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001544 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001545 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001546}
1547
ossu20a4b3f2017-04-27 02:08:52 -07001548// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001550 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].bitrate = 30000;
1554 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001555 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001556 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001557}
1558
stefan13f1a0a2016-11-30 07:22:58 -08001559TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1560 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1561 200000);
1562}
1563
1564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1565 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1566}
1567
1568TEST_F(WebRtcVoiceEngineTestFake,
1569 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1570 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1571}
1572
1573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1574 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1575}
1576
Yves Gerey665174f2018-06-19 15:03:05 +02001577TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001578 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1579 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001580 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001581 // Setting max bitrate should keep previous min bitrate
1582 // Setting max bitrate should not reset start bitrate.
1583 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1584 SetSdpBitrateParameters(
1585 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1586 Field(&BitrateConstraints::start_bitrate_bps, -1),
1587 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001588 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001589}
1590
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001591// Test that we can enable NACK with opus as caller.
1592TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001593 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001594 cricket::AudioSendParameters parameters;
1595 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001596 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1597 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001600 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601}
1602
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001603// Test that we can enable NACK with opus as callee.
1604TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001605 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters parameters;
1607 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001608 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1609 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001611 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001612 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001613 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001614
Yves Gerey665174f2018-06-19 15:03:05 +02001615 EXPECT_TRUE(
1616 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001617 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001618}
1619
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001620// Test that we can enable NACK on receive streams.
1621TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001622 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 cricket::AudioSendParameters parameters;
1625 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001626 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1627 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1629 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001630 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001631 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1632 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001633}
1634
1635// Test that we can disable NACK.
1636TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001637 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001638 cricket::AudioSendParameters parameters;
1639 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001640 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1641 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001642 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001643 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001644
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001645 parameters.codecs.clear();
1646 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001647 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001648 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001649}
1650
1651// Test that we can disable NACK on receive streams.
1652TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001653 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001655 cricket::AudioSendParameters parameters;
1656 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001657 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1658 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1661 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001663 parameters.codecs.clear();
1664 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1667 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668}
1669
1670// Test that NACK is enabled on a new receive stream.
1671TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001672 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001673 cricket::AudioSendParameters parameters;
1674 parameters.codecs.push_back(kIsacCodec);
1675 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001676 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1677 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001679 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680
solenberg2100c0b2017-03-01 11:29:29 -08001681 EXPECT_TRUE(AddRecvStream(kSsrcY));
1682 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1683 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1684 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685}
1686
stefanba4c0e42016-02-04 04:12:24 -08001687TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001689 cricket::AudioSendParameters send_parameters;
1690 send_parameters.codecs.push_back(kOpusCodec);
1691 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001693
1694 cricket::AudioRecvParameters recv_parameters;
1695 recv_parameters.codecs.push_back(kIsacCodec);
1696 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_TRUE(AddRecvStream(kSsrcX));
1698 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001699 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001700 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001701
ossudedfd282016-06-14 07:12:39 -07001702 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001704 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001705 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001706 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001707}
1708
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001709// Test that we can switch back and forth between Opus and ISAC with CN.
1710TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001711 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001712
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001713 cricket::AudioSendParameters opus_parameters;
1714 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001715 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001716 {
ossu20a4b3f2017-04-27 02:08:52 -07001717 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1718 EXPECT_EQ(111, spec.payload_type);
1719 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001720 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001722 cricket::AudioSendParameters isac_parameters;
1723 isac_parameters.codecs.push_back(kIsacCodec);
1724 isac_parameters.codecs.push_back(kCn16000Codec);
1725 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001727 {
ossu20a4b3f2017-04-27 02:08:52 -07001728 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1729 EXPECT_EQ(103, spec.payload_type);
1730 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001731 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732
solenberg059fb442016-10-26 05:12:24 -07001733 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001734 {
ossu20a4b3f2017-04-27 02:08:52 -07001735 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1736 EXPECT_EQ(111, spec.payload_type);
1737 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001738 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001739}
1740
1741// Test that we handle various ways of specifying bitrate.
1742TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001743 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters parameters;
1745 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001746 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001747 {
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(103, spec.payload_type);
1750 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1751 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001752 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001753
Yves Gerey665174f2018-06-19 15:03:05 +02001754 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001756 {
ossu20a4b3f2017-04-27 02:08:52 -07001757 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1758 EXPECT_EQ(103, spec.payload_type);
1759 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1760 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001761 }
Yves Gerey665174f2018-06-19 15:03:05 +02001762 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001763 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001764 {
ossu20a4b3f2017-04-27 02:08:52 -07001765 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1766 EXPECT_EQ(103, spec.payload_type);
1767 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1768 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001769 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770
Yves Gerey665174f2018-06-19 15:03:05 +02001771 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001772 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001773 {
ossu20a4b3f2017-04-27 02:08:52 -07001774 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1775 EXPECT_EQ(0, spec.payload_type);
1776 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1777 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001778 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779
Yves Gerey665174f2018-06-19 15:03:05 +02001780 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001782 {
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(0, spec.payload_type);
1785 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1786 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001787 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001788
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001789 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001790 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001792 {
ossu20a4b3f2017-04-27 02:08:52 -07001793 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1794 EXPECT_EQ(111, spec.payload_type);
1795 EXPECT_STREQ("opus", spec.format.name.c_str());
1796 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001797 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798}
1799
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001800// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001802 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 cricket::AudioSendParameters parameters;
1804 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001805}
1806
1807// Test that we can set send codecs even with telephone-event codec as the first
1808// one on the list.
1809TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001810 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001812 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 parameters.codecs.push_back(kIsacCodec);
1814 parameters.codecs.push_back(kPcmuCodec);
1815 parameters.codecs[0].id = 98; // DTMF
1816 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001818 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1819 EXPECT_EQ(96, spec.payload_type);
1820 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001821 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001822 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001823}
1824
Harald Alvestranda1f66612018-02-21 11:24:23 +01001825// Test that CanInsertDtmf() is governed by the send flag
1826TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1827 EXPECT_TRUE(SetupSendStream());
1828 cricket::AudioSendParameters parameters;
1829 parameters.codecs.push_back(kTelephoneEventCodec1);
1830 parameters.codecs.push_back(kPcmuCodec);
1831 parameters.codecs[0].id = 98; // DTMF
1832 parameters.codecs[1].id = 96;
1833 SetSendParameters(parameters);
1834 EXPECT_FALSE(channel_->CanInsertDtmf());
1835 SetSend(true);
1836 EXPECT_TRUE(channel_->CanInsertDtmf());
1837 SetSend(false);
1838 EXPECT_FALSE(channel_->CanInsertDtmf());
1839}
1840
solenberg31642aa2016-03-14 08:00:37 -07001841// Test that payload type range is limited for telephone-event codec.
1842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001843 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001844 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001845 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001846 parameters.codecs.push_back(kIsacCodec);
1847 parameters.codecs[0].id = 0; // DTMF
1848 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001849 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001850 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001851 EXPECT_TRUE(channel_->CanInsertDtmf());
1852 parameters.codecs[0].id = 128; // DTMF
1853 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1854 EXPECT_FALSE(channel_->CanInsertDtmf());
1855 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001856 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001857 EXPECT_TRUE(channel_->CanInsertDtmf());
1858 parameters.codecs[0].id = -1; // DTMF
1859 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1860 EXPECT_FALSE(channel_->CanInsertDtmf());
1861}
1862
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001863// Test that we can set send codecs even with CN codec as the first
1864// one on the list.
1865TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001866 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001867 cricket::AudioSendParameters parameters;
1868 parameters.codecs.push_back(kCn16000Codec);
1869 parameters.codecs.push_back(kIsacCodec);
1870 parameters.codecs.push_back(kPcmuCodec);
1871 parameters.codecs[0].id = 98; // wideband CN
1872 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001874 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1875 EXPECT_EQ(96, send_codec_spec.payload_type);
1876 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001877 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878}
1879
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001880// Test that we set VAD and DTMF types correctly as caller.
1881TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001882 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001883 cricket::AudioSendParameters parameters;
1884 parameters.codecs.push_back(kIsacCodec);
1885 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001886 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 parameters.codecs.push_back(kCn16000Codec);
1888 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001889 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 parameters.codecs[0].id = 96;
1891 parameters.codecs[2].id = 97; // wideband CN
1892 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001894 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1895 EXPECT_EQ(96, send_codec_spec.payload_type);
1896 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001897 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001898 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001899 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001900 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901}
1902
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001903// Test that we set VAD and DTMF types correctly as callee.
1904TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001905 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 cricket::AudioSendParameters parameters;
1907 parameters.codecs.push_back(kIsacCodec);
1908 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001909 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001910 parameters.codecs.push_back(kCn16000Codec);
1911 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001912 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001913 parameters.codecs[0].id = 96;
1914 parameters.codecs[2].id = 97; // wideband CN
1915 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001916 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001917 EXPECT_TRUE(
1918 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001919
ossu20a4b3f2017-04-27 02:08:52 -07001920 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1921 EXPECT_EQ(96, send_codec_spec.payload_type);
1922 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001923 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001924 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001925 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001926 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001927}
1928
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929// Test that we only apply VAD if we have a CN codec that matches the
1930// send codec clockrate.
1931TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001932 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001933 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001934 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001935 parameters.codecs.push_back(kIsacCodec);
1936 parameters.codecs.push_back(kCn16000Codec);
1937 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001938 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001939 {
ossu20a4b3f2017-04-27 02:08:52 -07001940 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1941 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001942 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001943 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001944 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001945 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001946 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001948 {
ossu20a4b3f2017-04-27 02:08:52 -07001949 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1950 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001951 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001952 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001953 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001954 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001955 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001956 {
ossu20a4b3f2017-04-27 02:08:52 -07001957 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1958 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001959 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001960 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001961 }
Brave Yao5225dd82015-03-26 07:39:19 +08001962 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001963 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001964 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001965 {
ossu20a4b3f2017-04-27 02:08:52 -07001966 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1967 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001968 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001969 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001970}
1971
1972// Test that we perform case-insensitive matching of codec names.
1973TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001974 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001975 cricket::AudioSendParameters parameters;
1976 parameters.codecs.push_back(kIsacCodec);
1977 parameters.codecs.push_back(kPcmuCodec);
1978 parameters.codecs.push_back(kCn16000Codec);
1979 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001980 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001981 parameters.codecs[0].name = "iSaC";
1982 parameters.codecs[0].id = 96;
1983 parameters.codecs[2].id = 97; // wideband CN
1984 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001986 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1987 EXPECT_EQ(96, send_codec_spec.payload_type);
1988 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001989 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001990 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001991 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001992 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001993}
1994
stefanba4c0e42016-02-04 04:12:24 -08001995class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1996 public:
1997 WebRtcVoiceEngineWithSendSideBweTest()
1998 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1999};
2000
2001TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2002 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002003 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002004 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002005 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2006 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2007 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002008 extension.id);
2009 return;
2010 }
2011 }
2012 FAIL() << "Transport sequence number extension not in header-extension list.";
2013}
2014
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002015// Test support for audio level header extension.
2016TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002017 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002018}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002019TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002020 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002021}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002022
solenbergd4adce42016-11-17 06:26:52 -08002023// Test support for transport sequence number header extension.
2024TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2025 TestSetSendRtpHeaderExtensions(
2026 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002027}
solenbergd4adce42016-11-17 06:26:52 -08002028TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2029 TestSetRecvRtpHeaderExtensions(
2030 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002031}
2032
solenberg1ac56142015-10-13 03:58:19 -07002033// Test that we can create a channel and start sending on it.
2034TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002035 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002036 SetSendParameters(send_parameters_);
2037 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002038 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002039 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002040 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002041}
2042
2043// Test that a channel will send if and only if it has a source and is enabled
2044// for sending.
2045TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002046 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002047 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002048 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002049 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002050 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2051 SetAudioSend(kSsrcX, true, &fake_source_);
2052 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2053 SetAudioSend(kSsrcX, true, nullptr);
2054 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002055}
2056
solenberg94218532016-06-16 10:53:22 -07002057// Test that a channel is muted/unmuted.
2058TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2059 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002060 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002061 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2062 SetAudioSend(kSsrcX, true, nullptr);
2063 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2064 SetAudioSend(kSsrcX, false, nullptr);
2065 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002066}
2067
solenberg6d6e7c52016-04-13 09:07:30 -07002068// Test that SetSendParameters() does not alter a stream's send state.
2069TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2070 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002072
2073 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002074 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002075 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002076
2077 // Changing RTP header extensions will recreate the AudioSendStream.
2078 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002079 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002080 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002082
2083 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002084 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002086
2087 // Changing RTP header extensions will recreate the AudioSendStream.
2088 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002089 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002091}
2092
solenberg1ac56142015-10-13 03:58:19 -07002093// Test that we can create a channel and start playing out on it.
2094TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002095 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002096 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002097 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002098 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002099 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002101}
2102
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103// Test that we can add and remove send streams.
2104TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2105 SetupForMultiSendStream();
2106
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002108 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109
solenbergc96df772015-10-21 13:01:53 -07002110 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002111 EXPECT_TRUE(
2112 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002113 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002115 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002116 }
tfarina5237aaf2015-11-10 23:44:30 -08002117 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118
solenbergc96df772015-10-21 13:01:53 -07002119 // Delete the send streams.
2120 for (uint32_t ssrc : kSsrcs4) {
2121 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002122 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002123 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124 }
solenbergc96df772015-10-21 13:01:53 -07002125 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126}
2127
2128// Test SetSendCodecs correctly configure the codecs in all send streams.
2129TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2130 SetupForMultiSendStream();
2131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002133 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002134 EXPECT_TRUE(
2135 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 }
2137
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002138 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002140 parameters.codecs.push_back(kIsacCodec);
2141 parameters.codecs.push_back(kCn16000Codec);
2142 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002143 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144
2145 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002146 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002147 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2148 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002149 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2150 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002151 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002152 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
2154
minyue7a973442016-10-20 03:27:12 -07002155 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002156 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002157 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002158 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002159 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2160 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002161 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2162 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002163 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164 }
2165}
2166
2167// Test we can SetSend on all send streams correctly.
2168TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2169 SetupForMultiSendStream();
2170
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002171 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002172 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002173 EXPECT_TRUE(
2174 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002175 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002176 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177 }
2178
2179 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002180 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002181 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002182 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002183 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002184 }
2185
2186 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002187 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002188 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002189 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002190 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002191 }
2192}
2193
2194// Test we can set the correct statistics on all send streams.
2195TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2196 SetupForMultiSendStream();
2197
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002198 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002199 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002200 EXPECT_TRUE(
2201 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002202 }
solenberg85a04962015-10-27 03:35:21 -07002203
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002204 // Create a receive stream to check that none of the send streams end up in
2205 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002206 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002207
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002209 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002210 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002211 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212
solenberg85a04962015-10-27 03:35:21 -07002213 // Check stats for the added streams.
2214 {
2215 cricket::VoiceMediaInfo info;
2216 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002217
solenberg85a04962015-10-27 03:35:21 -07002218 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002219 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002220 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002221 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002222 }
hbos1acfbd22016-11-17 23:43:29 -08002223 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002224
2225 // We have added one receive stream. We should see empty stats.
2226 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002227 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002228 }
solenberg1ac56142015-10-13 03:58:19 -07002229
solenberg2100c0b2017-03-01 11:29:29 -08002230 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002231 {
2232 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002233 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002234 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002235 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002236 EXPECT_EQ(0u, info.receivers.size());
2237 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002238
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002239 // Deliver a new packet - a default receive stream should be created and we
2240 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002241 {
2242 cricket::VoiceMediaInfo info;
2243 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2244 SetAudioReceiveStreamStats();
2245 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002246 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002247 EXPECT_EQ(1u, info.receivers.size());
2248 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002249 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002250 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002251}
2252
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002253// Test that we can add and remove receive streams, and do proper send/playout.
2254// We can receive on multiple streams while sending one stream.
2255TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002256 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002257
solenberg1ac56142015-10-13 03:58:19 -07002258 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002259 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002260 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002261
solenberg1ac56142015-10-13 03:58:19 -07002262 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002263 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002264 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002265 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002266
solenberg1ac56142015-10-13 03:58:19 -07002267 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002268 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002269
2270 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002271 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2272 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2273 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274
2275 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002276 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002277 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002278
2279 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002280 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002281 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2282 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002283
aleloi84ef6152016-08-04 05:28:21 -07002284 // Restart playout and make sure recv streams are played out.
2285 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2287 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288
aleloi84ef6152016-08-04 05:28:21 -07002289 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002290 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2291 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292}
2293
wu@webrtc.org97077a32013-10-25 21:18:33 +00002294TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002295 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002296 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2297 .Times(1)
2298 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002299 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2300 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002301 send_parameters_.options.tx_agc_target_dbov = 3;
2302 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2303 send_parameters_.options.tx_agc_limiter = true;
2304 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002305 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2306 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2307 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002308 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002309}
2310
minyue6b825df2016-10-31 04:08:32 -07002311TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2312 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002313 send_parameters_.options.audio_network_adaptor = true;
2314 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002315 SetSendParameters(send_parameters_);
2316 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002317 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002318}
2319
2320TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2321 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002322 send_parameters_.options.audio_network_adaptor = true;
2323 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002324 SetSendParameters(send_parameters_);
2325 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002326 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002327 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002328 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002329 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002330 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002331}
2332
2333TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2334 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002335 send_parameters_.options.audio_network_adaptor = true;
2336 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002337 SetSendParameters(send_parameters_);
2338 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002339 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002340 const int initial_num = call_.GetNumCreatedSendStreams();
2341 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002342 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002343 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2344 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002345 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002346 // AudioSendStream not expected to be recreated.
2347 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2348 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002349 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002350}
2351
michaelt6672b262017-01-11 10:17:59 -08002352class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2353 : public WebRtcVoiceEngineTestFake {
2354 public:
2355 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2356 : WebRtcVoiceEngineTestFake(
2357 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2358 "Enabled/") {}
2359};
2360
2361TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2362 EXPECT_TRUE(SetupSendStream());
2363 cricket::AudioSendParameters parameters;
2364 parameters.codecs.push_back(kOpusCodec);
2365 SetSendParameters(parameters);
2366 const int initial_num = call_.GetNumCreatedSendStreams();
2367 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2368
2369 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2370 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002371 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2372 constexpr int kMinOverheadBps =
2373 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002374
2375 constexpr int kOpusMinBitrateBps = 6000;
2376 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002377 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002378 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002379 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002380 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002381
Oskar Sundbom78807582017-11-16 11:09:55 +01002382 parameters.options.audio_network_adaptor = true;
2383 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002384 SetSendParameters(parameters);
2385
ossu11bfc532017-02-16 05:37:06 -08002386 constexpr int kMinOverheadWithAnaBps =
2387 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002388
2389 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002390 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002391
minyuececec102017-03-27 13:04:25 -07002392 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002393 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002394}
2395
minyuececec102017-03-27 13:04:25 -07002396// This test is similar to
2397// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2398// additional field trial.
2399TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2400 SetRtpSendParameterUpdatesMaxBitrate) {
2401 EXPECT_TRUE(SetupSendStream());
2402 cricket::AudioSendParameters send_parameters;
2403 send_parameters.codecs.push_back(kOpusCodec);
2404 SetSendParameters(send_parameters);
2405
2406 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2407 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2408 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2409
2410 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002411 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002412 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002413
2414 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2415#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2416 constexpr int kMinOverhead = 3333;
2417#else
2418 constexpr int kMinOverhead = 6666;
2419#endif
2420 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2421}
2422
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002424// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002426 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002427 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428}
2429
2430TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2431 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002433 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002434 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002435 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002436 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002437 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002438 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439
solenberg85a04962015-10-27 03:35:21 -07002440 // Check stats for the added streams.
2441 {
2442 cricket::VoiceMediaInfo info;
2443 EXPECT_EQ(true, channel_->GetStats(&info));
2444
2445 // We have added one send stream. We should see the stats we've set.
2446 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002447 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002448 // We have added one receive stream. We should see empty stats.
2449 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002450 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002451 }
solenberg1ac56142015-10-13 03:58:19 -07002452
solenberg566ef242015-11-06 15:34:49 -08002453 // Start sending - this affects some reported stats.
2454 {
2455 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002456 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002457 EXPECT_EQ(true, channel_->GetStats(&info));
2458 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002459 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002460 }
2461
solenberg2100c0b2017-03-01 11:29:29 -08002462 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002463 {
2464 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002465 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002466 EXPECT_EQ(true, channel_->GetStats(&info));
2467 EXPECT_EQ(1u, info.senders.size());
2468 EXPECT_EQ(0u, info.receivers.size());
2469 }
solenberg1ac56142015-10-13 03:58:19 -07002470
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002471 // Deliver a new packet - a default receive stream should be created and we
2472 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002473 {
2474 cricket::VoiceMediaInfo info;
2475 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2476 SetAudioReceiveStreamStats();
2477 EXPECT_EQ(true, channel_->GetStats(&info));
2478 EXPECT_EQ(1u, info.senders.size());
2479 EXPECT_EQ(1u, info.receivers.size());
2480 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002481 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002482 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483}
2484
2485// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002486// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002489 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2490 EXPECT_TRUE(AddRecvStream(kSsrcY));
2491 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492}
2493
2494// Test that the local SSRC is the same on sending and receiving channels if the
2495// receive channel is created before the send channel.
2496TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002497 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002498 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002499 EXPECT_TRUE(
2500 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002501 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2502 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503}
2504
2505// Test that we can properly receive packets.
2506TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002507 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002508 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002510
Yves Gerey665174f2018-06-19 15:03:05 +02002511 EXPECT_TRUE(
2512 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513}
2514
2515// Test that we can properly receive packets on multiple streams.
2516TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002517 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002518 const uint32_t ssrc1 = 1;
2519 const uint32_t ssrc2 = 2;
2520 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002521 EXPECT_TRUE(AddRecvStream(ssrc1));
2522 EXPECT_TRUE(AddRecvStream(ssrc2));
2523 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002525 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002526 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002528 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529 }
mflodman3d7db262016-04-29 00:57:13 -07002530
2531 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2532 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2533 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2534
2535 EXPECT_EQ(s1.received_packets(), 0);
2536 EXPECT_EQ(s2.received_packets(), 0);
2537 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002538
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002539 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002540 EXPECT_EQ(s1.received_packets(), 0);
2541 EXPECT_EQ(s2.received_packets(), 0);
2542 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002543
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002545 EXPECT_EQ(s1.received_packets(), 1);
2546 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2547 EXPECT_EQ(s2.received_packets(), 0);
2548 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002549
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002550 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002551 EXPECT_EQ(s1.received_packets(), 1);
2552 EXPECT_EQ(s2.received_packets(), 1);
2553 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2554 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002555
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002557 EXPECT_EQ(s1.received_packets(), 1);
2558 EXPECT_EQ(s2.received_packets(), 1);
2559 EXPECT_EQ(s3.received_packets(), 1);
2560 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002561
mflodman3d7db262016-04-29 00:57:13 -07002562 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2563 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2564 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565}
2566
solenberg2100c0b2017-03-01 11:29:29 -08002567// Test that receiving on an unsignaled stream works (a stream is created).
2568TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002569 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002570 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002571
solenberg7e63ef02015-11-20 00:19:43 -08002572 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002573
Mirko Bonadeif859e552018-05-30 15:31:29 +02002574 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002575 EXPECT_TRUE(
2576 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002577}
2578
Seth Hampson5897a6e2018-04-03 11:16:33 -07002579// Tests that when we add a stream without SSRCs, but contains a stream_id
2580// that it is stored and its stream id is later used when the first packet
2581// arrives to properly create a receive stream with a sync label.
2582TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2583 const char kSyncLabel[] = "sync_label";
2584 EXPECT_TRUE(SetupChannel());
2585 cricket::StreamParams unsignaled_stream;
2586 unsignaled_stream.set_stream_ids({kSyncLabel});
2587 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2588 // The stream shouldn't have been created at this point because it doesn't
2589 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002590 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002591
2592 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2593
Mirko Bonadeif859e552018-05-30 15:31:29 +02002594 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002595 EXPECT_TRUE(
2596 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2597 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2598
2599 // Removing the unsignaled stream clears the cached parameters. If a new
2600 // default unsignaled receive stream is created it will not have a sync group.
2601 channel_->RemoveRecvStream(0);
2602 channel_->RemoveRecvStream(kSsrc1);
2603
2604 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2605
Mirko Bonadeif859e552018-05-30 15:31:29 +02002606 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002607 EXPECT_TRUE(
2608 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2609 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2610}
2611
solenberg2100c0b2017-03-01 11:29:29 -08002612// Test that receiving N unsignaled stream works (streams will be created), and
2613// that packets are forwarded to them all.
2614TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002615 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002616 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002617 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2618
solenberg2100c0b2017-03-01 11:29:29 -08002619 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002620 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002621 rtc::SetBE32(&packet[8], ssrc);
2622 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002623
solenberg2100c0b2017-03-01 11:29:29 -08002624 // Verify we have one new stream for each loop iteration.
2625 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002626 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2627 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002628 }
mflodman3d7db262016-04-29 00:57:13 -07002629
solenberg2100c0b2017-03-01 11:29:29 -08002630 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002631 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002632 rtc::SetBE32(&packet[8], ssrc);
2633 DeliverPacket(packet, sizeof(packet));
2634
solenbergebb349d2017-03-13 05:46:15 -07002635 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002636 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2637 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2638 }
2639
2640 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2641 constexpr uint32_t kAnotherSsrc = 667;
2642 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002643 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002644
2645 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002646 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002647 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002648 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002649 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2650 EXPECT_EQ(2, streams[i]->received_packets());
2651 }
2652 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2653 EXPECT_EQ(1, streams[i]->received_packets());
2654 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002655 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002656}
2657
solenberg2100c0b2017-03-01 11:29:29 -08002658// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002659// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002660TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002661 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002662 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002663 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2664
2665 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002666 const uint32_t signaled_ssrc = 1;
2667 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002669 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002670 EXPECT_TRUE(
2671 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002672 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002673
2674 // Note that the first unknown SSRC cannot be 0, because we only support
2675 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002676 const uint32_t unsignaled_ssrc = 7011;
2677 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002678 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002679 EXPECT_TRUE(
2680 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002681 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002682
2683 DeliverPacket(packet, sizeof(packet));
2684 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2685
2686 rtc::SetBE32(&packet[8], signaled_ssrc);
2687 DeliverPacket(packet, sizeof(packet));
2688 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002689 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002690}
2691
solenberg4904fb62017-02-17 12:01:14 -08002692// Two tests to verify that adding a receive stream with the same SSRC as a
2693// previously added unsignaled stream will only recreate underlying stream
2694// objects if the stream parameters have changed.
2695TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2696 EXPECT_TRUE(SetupChannel());
2697
2698 // Spawn unsignaled stream with SSRC=1.
2699 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002700 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002701 EXPECT_TRUE(
2702 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002703
2704 // Verify that the underlying stream object in Call is not recreated when a
2705 // stream with SSRC=1 is added.
2706 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002707 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002708 int audio_receive_stream_id = streams.front()->id();
2709 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002710 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002711 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2712}
2713
2714TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2715 EXPECT_TRUE(SetupChannel());
2716
2717 // Spawn unsignaled stream with SSRC=1.
2718 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002719 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002720 EXPECT_TRUE(
2721 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002722
2723 // Verify that the underlying stream object in Call *is* recreated when a
2724 // stream with SSRC=1 is added, and which has changed stream parameters.
2725 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002726 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002727 int audio_receive_stream_id = streams.front()->id();
2728 cricket::StreamParams stream_params;
2729 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002730 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002731 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002732 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002733 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2734}
2735
solenberg1ac56142015-10-13 03:58:19 -07002736// Test that AddRecvStream creates new stream.
2737TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002738 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002739 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740}
2741
2742// Test that after adding a recv stream, we do not decode more codecs than
2743// those previously passed into SetRecvCodecs.
2744TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002745 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002746 cricket::AudioRecvParameters parameters;
2747 parameters.codecs.push_back(kIsacCodec);
2748 parameters.codecs.push_back(kPcmuCodec);
2749 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002750 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002751 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2752 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2753 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754}
2755
2756// Test that we properly clean up any streams that were added, even if
2757// not explicitly removed.
2758TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002761 EXPECT_TRUE(AddRecvStream(1));
2762 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002763
Mirko Bonadeif859e552018-05-30 15:31:29 +02002764 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2765 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766 delete channel_;
2767 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002768 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2769 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770}
2771
wu@webrtc.org78187522013-10-07 23:32:02 +00002772TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002773 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002774 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002775}
2776
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002777TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002778 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002779 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002780 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002781}
2782
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002783// Test the InsertDtmf on default send stream as caller.
2784TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002785 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786}
2787
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002788// Test the InsertDtmf on default send stream as callee
2789TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002790 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002791}
2792
2793// Test the InsertDtmf on specified send stream as caller.
2794TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002795 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002796}
2797
2798// Test the InsertDtmf on specified send stream as callee.
2799TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002800 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002803TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002804 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002805 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002806 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2807 .Times(9)
2808 .WillRepeatedly(Return(false));
2809 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2810 .Times(4)
2811 .WillRepeatedly(Return(false));
2812 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2813 .Times(2)
2814 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002815
Mirko Bonadeif859e552018-05-30 15:31:29 +02002816 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002817 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818
solenberg246b8172015-12-08 09:50:23 -08002819 // Nothing set in AudioOptions, so everything should be as default.
2820 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002821 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002822 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002823 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002824 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002825 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002826
2827 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002828 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002830 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831
2832 // Turn echo cancellation back on, with settings, and make sure
2833 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002834 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002835 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002836 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002838 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2839 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002840 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002841 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002842 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002843
2844 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002845 send_parameters_.options.delay_agnostic_aec = false;
2846 send_parameters_.options.extended_filter_aec = false;
2847 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002848 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002849 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002850
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002851 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002852 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002853 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002854 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002855
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002857 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002859 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002860 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002861 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002862
2863 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002864 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002865 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002866 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002867 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002868 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002870 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002871 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002873 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002876 send_parameters_.options.noise_suppression = false;
2877 send_parameters_.options.highpass_filter = false;
2878 send_parameters_.options.typing_detection = false;
2879 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002880 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002881 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002882 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883
solenberg1ac56142015-10-13 03:58:19 -07002884 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002885 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002890 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002891 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892}
2893
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002894TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002895 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002896 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2897 .Times(8)
2898 .WillRepeatedly(Return(false));
2899 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2900 .Times(8)
2901 .WillRepeatedly(Return(false));
2902 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2903 .Times(8)
2904 .WillRepeatedly(Return(false));
2905 EXPECT_CALL(adm_, RecordingIsInitialized())
2906 .Times(2)
2907 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002908 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2909 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002910 webrtc::AudioProcessing::Config apm_config;
2911 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002912 .WillRepeatedly(ReturnPointee(&apm_config));
2913 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002914 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002915 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002916
kwiberg686a8ef2016-02-26 03:00:35 -08002917 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002918 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002919 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2920 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002921 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002922 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002923 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2924 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925
2926 // Have to add a stream to make SetSend work.
2927 cricket::StreamParams stream1;
2928 stream1.ssrcs.push_back(1);
2929 channel1->AddSendStream(stream1);
2930 cricket::StreamParams stream2;
2931 stream2.ssrcs.push_back(2);
2932 channel2->AddSendStream(stream2);
2933
2934 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002935 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002936 parameters_options_all.options.echo_cancellation = true;
2937 parameters_options_all.options.auto_gain_control = true;
2938 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002941 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002942 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002943 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002944 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002946 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002947 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002948 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949
2950 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002951 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002952 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002953 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002954 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002955 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002956 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002957 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002958 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002960 expected_options.echo_cancellation = true;
2961 expected_options.auto_gain_control = true;
2962 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002963 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002964
2965 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002966 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002967 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002968 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002969 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002970 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002972 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002973 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01002974 expected_options.echo_cancellation = true;
2975 expected_options.auto_gain_control = false;
2976 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002977 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002979 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002980 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002981 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002982 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002983 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002984 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002986 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002987 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002988 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002989 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002990 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002991 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002993 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002994 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002995 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002996 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002997 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002998 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3002 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003003 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3004 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003005 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003006 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003007 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003008 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003009 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003010 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003011 expected_options.echo_cancellation = true;
3012 expected_options.auto_gain_control = false;
3013 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003014 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015}
3016
wu@webrtc.orgde305012013-10-31 15:40:38 +00003017// This test verifies DSCP settings are properly applied on voice media channel.
3018TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003019 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003020 cricket::FakeNetworkInterface network_interface;
3021 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003022 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003023
peahb1c9d1d2017-07-25 15:45:24 -07003024 webrtc::AudioProcessing::Config apm_config;
3025 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003026 .WillRepeatedly(ReturnPointee(&apm_config));
3027 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003028 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003029 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003030
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003031 channel.reset(
3032 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3033 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003034 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003035 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3036 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3037
3038 config.enable_dscp = true;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003039 channel.reset(
3040 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3041 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003042 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003043 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3044
Tim Haloun6ca98362018-09-17 17:06:08 -07003045 // Packets should also self-identify their dscp in PacketOptions.
3046 const uint8_t kData[10] = {0};
3047 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
3048 EXPECT_EQ(rtc::DSCP_EF, network_interface.options().dscp);
3049
nisse51542be2016-02-12 02:27:06 -08003050 // Verify that setting the option to false resets the
3051 // DiffServCodePoint.
3052 config.enable_dscp = false;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003053 channel.reset(
3054 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3055 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003056 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003057 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3058 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3059
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003060 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003061}
3062
solenberg4bac9c52015-10-09 02:32:53 -07003063TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003064 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003065 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003067 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003068 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003069 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3070 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3071 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003072}
3073
solenberg2100c0b2017-03-01 11:29:29 -08003074TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003075 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003076
3077 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003078 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003079 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3080
3081 // Should remember the volume "2" which will be set on new unsignaled streams,
3082 // and also set the gain to 2 on existing unsignaled streams.
3083 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3084 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3085
3086 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3087 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3088 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3089 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3090 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3091 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3092
3093 // Setting gain with SSRC=0 should affect all unsignaled streams.
3094 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003095 if (kMaxUnsignaledRecvStreams > 1) {
3096 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3097 }
solenberg2100c0b2017-03-01 11:29:29 -08003098 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3099
3100 // Setting gain on an individual stream affects only that.
3101 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003102 if (kMaxUnsignaledRecvStreams > 1) {
3103 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3104 }
solenberg2100c0b2017-03-01 11:29:29 -08003105 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003106}
3107
Seth Hampson845e8782018-03-02 11:34:10 -08003108TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003109 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003110 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003111
solenbergff976312016-03-30 23:28:51 -07003112 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003113 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003114 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003115 // Creating two channels to make sure that sync label is set properly for both
3116 // the default voice channel and following ones.
3117 EXPECT_TRUE(channel_->AddRecvStream(sp));
3118 sp.ssrcs[0] += 1;
3119 EXPECT_TRUE(channel_->AddRecvStream(sp));
3120
Mirko Bonadeif859e552018-05-30 15:31:29 +02003121 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003122 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003123 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003124 << "SyncGroup should be set based on stream id";
3125 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003126 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003127 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003128}
3129
solenberg3a941542015-11-16 07:34:50 -08003130// TODO(solenberg): Remove, once recv streams are configured through Call.
3131// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003132TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003133 // Test that setting the header extensions results in the expected state
3134 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003135 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003136 ssrcs.push_back(223);
3137 ssrcs.push_back(224);
3138
solenbergff976312016-03-30 23:28:51 -07003139 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003140 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003141 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003142 EXPECT_TRUE(
3143 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003144 }
3145
Mirko Bonadeif859e552018-05-30 15:31:29 +02003146 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003147 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003148 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003149 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003150 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003151 }
3152
3153 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003154 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003155 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003156 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003157 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003158 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003159 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003160 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003161 EXPECT_NE(nullptr, s);
3162 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003163 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3164 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003165 for (const auto& s_ext : s_exts) {
3166 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003167 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003168 }
3169 }
3170 }
3171 }
3172
3173 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003174 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003175 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003176 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003177 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003178 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003179 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003180}
3181
3182TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3183 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003184 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003185 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003186 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003187 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3188 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003190 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003191
solenbergff976312016-03-30 23:28:51 -07003192 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003193 cricket::WebRtcVoiceMediaChannel* media_channel =
3194 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003195 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003196 EXPECT_TRUE(media_channel->AddRecvStream(
3197 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3198
Mirko Bonadeif859e552018-05-30 15:31:29 +02003199 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003201 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003202 EXPECT_EQ(0, s->received_packets());
3203 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3204 EXPECT_EQ(1, s->received_packets());
3205 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3206 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003207}
Minyue2013aec2015-05-13 14:14:42 +02003208
solenberg0a617e22015-10-20 15:49:38 -07003209// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003210// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003211TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003212 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003213 EXPECT_TRUE(AddRecvStream(kSsrcY));
3214 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003215 EXPECT_TRUE(
3216 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003217 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3218 EXPECT_TRUE(AddRecvStream(kSsrcW));
3219 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003220}
3221
solenberg7602aab2016-11-14 11:30:07 -08003222TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3223 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003224 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003225 EXPECT_TRUE(
3226 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003227 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3228 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3229 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003230 EXPECT_TRUE(
3231 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003232 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3233 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003234}
stefan658910c2015-09-03 05:48:32 -07003235
deadbeef884f5852016-01-15 09:20:04 -08003236TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003237 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003238 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3239 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003240
3241 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003242 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3243 EXPECT_TRUE(AddRecvStream(kSsrcX));
3244 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003245
3246 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003247 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3248 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003249
3250 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003251 channel_->SetRawAudioSink(kSsrcX, nullptr);
3252 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003253}
3254
solenberg2100c0b2017-03-01 11:29:29 -08003255TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003256 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003257 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3258 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003259 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3260 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003261
3262 // Should be able to set a default sink even when no stream exists.
3263 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3264
solenberg2100c0b2017-03-01 11:29:29 -08003265 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3266 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003267 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003268 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003269
3270 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003271 channel_->SetRawAudioSink(kSsrc0, nullptr);
3272 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003273
3274 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003275 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3276 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003277
3278 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003280 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3282
3283 // Spawn another unsignaled stream - it should be assigned the default sink
3284 // and the previous unsignaled stream should lose it.
3285 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3286 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3287 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3288 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003289 if (kMaxUnsignaledRecvStreams > 1) {
3290 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3291 }
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3293
3294 // Reset the default sink - the second unsignaled stream should lose it.
3295 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003296 if (kMaxUnsignaledRecvStreams > 1) {
3297 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3298 }
solenberg2100c0b2017-03-01 11:29:29 -08003299 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3300
3301 // Try setting the default sink while two streams exists.
3302 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003303 if (kMaxUnsignaledRecvStreams > 1) {
3304 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3305 }
solenberg2100c0b2017-03-01 11:29:29 -08003306 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3307
3308 // Try setting the sink for the first unsignaled stream using its known SSRC.
3309 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003310 if (kMaxUnsignaledRecvStreams > 1) {
3311 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3312 }
solenberg2100c0b2017-03-01 11:29:29 -08003313 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003314 if (kMaxUnsignaledRecvStreams > 1) {
3315 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3316 }
deadbeef884f5852016-01-15 09:20:04 -08003317}
3318
skvlad7a43d252016-03-22 15:32:27 -07003319// Test that, just like the video channel, the voice channel communicates the
3320// network state to the call.
3321TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003322 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003323
3324 EXPECT_EQ(webrtc::kNetworkUp,
3325 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3326 EXPECT_EQ(webrtc::kNetworkUp,
3327 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3328
3329 channel_->OnReadyToSend(false);
3330 EXPECT_EQ(webrtc::kNetworkDown,
3331 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3332 EXPECT_EQ(webrtc::kNetworkUp,
3333 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3334
3335 channel_->OnReadyToSend(true);
3336 EXPECT_EQ(webrtc::kNetworkUp,
3337 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3338 EXPECT_EQ(webrtc::kNetworkUp,
3339 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3340}
3341
aleloi18e0b672016-10-04 02:45:47 -07003342// Test that playout is still started after changing parameters
3343TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3344 SetupRecvStream();
3345 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003347
3348 // Changing RTP header extensions will recreate the AudioReceiveStream.
3349 cricket::AudioRecvParameters parameters;
3350 parameters.extensions.push_back(
3351 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3352 channel_->SetRecvParameters(parameters);
3353
solenberg2100c0b2017-03-01 11:29:29 -08003354 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003355}
3356
Zhi Huangfa266ef2017-12-13 10:27:46 -08003357// Tests when GetSources is called with non-existing ssrc, it will return an
3358// empty list of RtpSource without crashing.
3359TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3360 // Setup an recv stream with |kSsrcX|.
3361 SetupRecvStream();
3362 cricket::WebRtcVoiceMediaChannel* media_channel =
3363 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3364 // Call GetSources with |kSsrcY| which doesn't exist.
3365 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3366 EXPECT_EQ(0u, sources.size());
3367}
3368
stefan658910c2015-09-03 05:48:32 -07003369// Tests that the library initializes and shuts down properly.
3370TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003371 // If the VoiceEngine wants to gather available codecs early, that's fine but
3372 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003373 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003374 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003375 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003376 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003377 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003378 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003379 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003380 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003381 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003382 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003383 cricket::VoiceMediaChannel* channel =
3384 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3385 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003386 EXPECT_TRUE(channel != nullptr);
3387 delete channel;
solenbergff976312016-03-30 23:28:51 -07003388}
stefan658910c2015-09-03 05:48:32 -07003389
solenbergff976312016-03-30 23:28:51 -07003390// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003391TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3392 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003393 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003394 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003395 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003396 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003397 {
peaha9cc40b2017-06-29 08:32:09 -07003398 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003399 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003400 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003401 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003402 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003403 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003404 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003405 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003406 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003407 cricket::VoiceMediaChannel* channel =
3408 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3409 cricket::AudioOptions(), webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003410 EXPECT_TRUE(channel != nullptr);
3411 delete channel;
3412 }
stefan658910c2015-09-03 05:48:32 -07003413}
3414
ossu20a4b3f2017-04-27 02:08:52 -07003415// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3416TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003417 // TODO(ossu): Why are the payload types of codecs with non-static payload
3418 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003419 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003420 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003421 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003422 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003423 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003424 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003425 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003426 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003427 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3428 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3429 (clockrate == 0 || codec.clockrate == clockrate);
3430 };
3431 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003432 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003433 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003434 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003435 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003436 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003437 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003438 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003439 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003440 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003441 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003442 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003443 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3444 // Remove these checks once both send and receive side assigns payload
3445 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003446 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003447 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003448 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003449 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003450 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003451 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003452 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003453 EXPECT_EQ(111, codec.id);
3454 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3455 EXPECT_EQ("10", codec.params.find("minptime")->second);
3456 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3457 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003458 }
3459 }
stefan658910c2015-09-03 05:48:32 -07003460}
3461
3462// Tests that VoE supports at least 32 channels
3463TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003464 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003465 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003466 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003467 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003468 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003469 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003470 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003471 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003472 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003473 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003474
3475 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003476 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003477 while (num_channels < arraysize(channels)) {
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003478 cricket::VoiceMediaChannel* channel =
3479 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3480 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003481 if (!channel)
3482 break;
stefan658910c2015-09-03 05:48:32 -07003483 channels[num_channels++] = channel;
3484 }
3485
Mirko Bonadeif859e552018-05-30 15:31:29 +02003486 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003487 EXPECT_EQ(expected, num_channels);
3488
3489 while (num_channels > 0) {
3490 delete channels[--num_channels];
3491 }
stefan658910c2015-09-03 05:48:32 -07003492}
3493
3494// Test that we set our preferred codecs properly.
3495TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003496 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3497 // - Check that our builtin codecs are usable by Channel.
3498 // - The codecs provided by the engine is usable by Channel.
3499 // It does not check that the codecs in the RecvParameters are actually
3500 // what we sent in - though it's probably reasonable to expect so, if
3501 // SetRecvParameters returns true.
3502 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003503 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003504 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003505 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003506 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003507 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003508 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003509 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003510 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003511 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003512 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003513 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003514 cricket::AudioOptions(),
3515 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003516 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003517 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003518 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003519}
ossu9def8002017-02-09 05:14:32 -08003520
3521TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3522 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003523 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3524 {48000, 2, 16000, 10000, 20000}};
3525 spec1.info.allow_comfort_noise = false;
3526 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003527 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003528 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3529 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003530 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003531 specs.push_back(webrtc::AudioCodecSpec{
3532 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3533 {16000, 1, 13300}});
3534 specs.push_back(
3535 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3536 specs.push_back(
3537 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003538
ossueb1fde42017-05-02 06:46:30 -07003539 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3540 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3541 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003542 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003543 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003544 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003545 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003546
peaha9cc40b2017-06-29 08:32:09 -07003547 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003548 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003549 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003550 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003551 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003552 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003553 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003554
3555 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3556 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003557 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3558 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3559 if (codecs.size() > index)
3560 return codecs[index];
3561 return missing_codec;
3562 };
ossu9def8002017-02-09 05:14:32 -08003563
3564 // Ensure the general codecs are generated first and in order.
3565 for (size_t i = 0; i != specs.size(); ++i) {
3566 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3567 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3568 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3569 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3570 }
3571
3572 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003573 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003574 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3575 for (size_t i = 0; i != codecs.size(); ++i) {
3576 const cricket::AudioCodec& codec = codecs[i];
3577 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3578 codec.clockrate == format.clockrate_hz &&
3579 codec.channels == format.num_channels) {
3580 return rtc::checked_cast<int>(i);
3581 }
3582 }
3583 return -1;
3584 };
ossu9def8002017-02-09 05:14:32 -08003585
3586 // Ensure all supplementary codecs are generated last. Their internal ordering
3587 // is not important.
3588 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3589 const int num_specs = static_cast<int>(specs.size());
3590 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3591 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3592 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3593 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3594 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3595 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3596 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3597}