blob: 095d8b240b03a69bfd22015b4bb17086806dd06d [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
Tim Haloun648d28a2018-10-18 16:52:22 -07001141// RTCRtpEncodingParameters.network_priority must be one of a few values
1142// derived from the default priority, corresponding to very-low, low, medium,
1143// or high.
1144TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1145 EXPECT_TRUE(SetupSendStream());
1146 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1147 EXPECT_EQ(1UL, parameters.encodings.size());
1148 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1149 parameters.encodings[0].network_priority);
1150
1151 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1152 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1153 for (auto it : good_values) {
1154 parameters.encodings[0].network_priority = it;
1155 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1156 }
1157 for (auto it : bad_values) {
1158 parameters.encodings[0].network_priority = it;
1159 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1160 }
1161}
1162
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001163// Test that GetRtpSendParameters returns the currently configured codecs.
1164TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165 EXPECT_TRUE(SetupSendStream());
1166 cricket::AudioSendParameters parameters;
1167 parameters.codecs.push_back(kIsacCodec);
1168 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001169 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170
solenberg2100c0b2017-03-01 11:29:29 -08001171 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001172 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001173 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1174 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175}
1176
Florent Castellidacec712018-05-24 16:24:21 +02001177// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1178TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1179 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1180 params.cname = "rtcpcname";
1181 EXPECT_TRUE(SetupSendStream(params));
1182
1183 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1184 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1185}
1186
Florent Castelliabe301f2018-06-12 18:33:49 +02001187TEST_F(WebRtcVoiceEngineTestFake,
1188 DetectRtpSendParameterHeaderExtensionsChange) {
1189 EXPECT_TRUE(SetupSendStream());
1190
1191 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1192 rtp_parameters.header_extensions.emplace_back();
1193
1194 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1195
1196 webrtc::RTCError result =
1197 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1198 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1199}
1200
deadbeefcb443432016-12-12 11:12:36 -08001201// Test that GetRtpSendParameters returns an SSRC.
1202TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1203 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001204 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001205 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001206 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001207}
1208
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001209// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001211 EXPECT_TRUE(SetupSendStream());
1212 cricket::AudioSendParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001215 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001216
solenberg2100c0b2017-03-01 11:29:29 -08001217 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218
1219 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001220 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001221
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001222 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001223 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1224 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225}
1226
minyuececec102017-03-27 13:04:25 -07001227// Test that max_bitrate_bps in send stream config gets updated correctly when
1228// SetRtpSendParameters is called.
1229TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1230 webrtc::test::ScopedFieldTrials override_field_trials(
1231 "WebRTC-Audio-SendSideBwe/Enabled/");
1232 EXPECT_TRUE(SetupSendStream());
1233 cricket::AudioSendParameters send_parameters;
1234 send_parameters.codecs.push_back(kOpusCodec);
1235 SetSendParameters(send_parameters);
1236
1237 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1238 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1239 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1240
1241 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001242 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001243 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001244
1245 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1246 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1247}
1248
Seth Hampson24722b32017-12-22 09:36:42 -08001249// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1250// a value <= 0, setting the parameters returns false.
1251TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1252 EXPECT_TRUE(SetupSendStream());
1253 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1254 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1255 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1256 rtp_parameters.encodings[0].bitrate_priority);
1257
1258 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001259 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001260 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001261 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001262}
1263
1264// Test that the bitrate_priority in the send stream config gets updated when
1265// SetRtpSendParameters is set for the VoiceMediaChannel.
1266TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1267 EXPECT_TRUE(SetupSendStream());
1268 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1269
1270 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1271 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1272 rtp_parameters.encodings[0].bitrate_priority);
1273 double new_bitrate_priority = 2.0;
1274 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001275 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001276
1277 // The priority should get set for both the audio channel's rtp parameters
1278 // and the audio send stream's audio config.
1279 EXPECT_EQ(
1280 new_bitrate_priority,
1281 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1282 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1283}
1284
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001285// Test that GetRtpReceiveParameters returns the currently configured codecs.
1286TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1287 EXPECT_TRUE(SetupRecvStream());
1288 cricket::AudioRecvParameters parameters;
1289 parameters.codecs.push_back(kIsacCodec);
1290 parameters.codecs.push_back(kPcmuCodec);
1291 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1292
1293 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001294 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001295 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1296 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1297 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1298}
1299
deadbeefcb443432016-12-12 11:12:36 -08001300// Test that GetRtpReceiveParameters returns an SSRC.
1301TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1302 EXPECT_TRUE(SetupRecvStream());
1303 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001304 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001305 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001306 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001307}
1308
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001309// Test that if we set/get parameters multiple times, we get the same results.
1310TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1311 EXPECT_TRUE(SetupRecvStream());
1312 cricket::AudioRecvParameters parameters;
1313 parameters.codecs.push_back(kIsacCodec);
1314 parameters.codecs.push_back(kPcmuCodec);
1315 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1316
1317 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001318 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001319
1320 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001321 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001322
1323 // ... And this shouldn't change the params returned by
1324 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001325 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1326 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001327}
1328
deadbeef3bc15102017-04-20 19:25:07 -07001329// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1330// aren't signaled. It should return an empty "RtpEncodingParameters" when
1331// configured to receive an unsignaled stream and no packets have been received
1332// yet, and start returning the SSRC once a packet has been received.
1333TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1334 ASSERT_TRUE(SetupChannel());
1335 // Call necessary methods to configure receiving a default stream as
1336 // soon as it arrives.
1337 cricket::AudioRecvParameters parameters;
1338 parameters.codecs.push_back(kIsacCodec);
1339 parameters.codecs.push_back(kPcmuCodec);
1340 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1341
1342 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1343 // stream. Should return nothing.
1344 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1345
1346 // Set a sink for an unsignaled stream.
1347 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1348 // Value of "0" means "unsignaled stream".
1349 channel_->SetRawAudioSink(0, std::move(fake_sink));
1350
1351 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1352 // in this method means "unsignaled stream".
1353 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1354 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1355 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1356
1357 // Receive PCMU packet (SSRC=1).
1358 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1359
1360 // The |ssrc| member should still be unset.
1361 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1362 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1363 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1364}
1365
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366// Test that we apply codecs properly.
1367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001368 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 cricket::AudioSendParameters parameters;
1370 parameters.codecs.push_back(kIsacCodec);
1371 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001372 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001374 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001375 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001376 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1377 EXPECT_EQ(96, send_codec_spec.payload_type);
1378 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1379 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1380 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001381 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001382 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383}
1384
ossu20a4b3f2017-04-27 02:08:52 -07001385// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1386// AudioSendStream.
1387TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kIsacCodec);
1391 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001392 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 parameters.codecs[0].id = 96;
1394 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001395 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001396 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001397 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001398 // Calling SetSendCodec again with same codec which is already set.
1399 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001400 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001401 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001402}
1403
ossu20a4b3f2017-04-27 02:08:52 -07001404// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1405// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001406
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001407// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001409 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 cricket::AudioSendParameters parameters;
1411 parameters.codecs.push_back(kOpusCodec);
1412 parameters.codecs[0].bitrate = 0;
1413 parameters.codecs[0].clockrate = 50000;
1414 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001417// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 0;
1423 parameters.codecs[0].channels = 0;
1424 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425}
1426
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001427// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].bitrate = 0;
1433 parameters.codecs[0].channels = 0;
1434 parameters.codecs[0].params["stereo"] = "1";
1435 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436}
1437
1438// Test that if channel is 1 for opus and there's no stereo, we fail.
1439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].bitrate = 0;
1444 parameters.codecs[0].channels = 1;
1445 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
1448// Test that if channel is 1 for opus and stereo=0, we fail.
1449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
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;
1454 parameters.codecs[0].channels = 1;
1455 parameters.codecs[0].params["stereo"] = "0";
1456 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457}
1458
1459// Test that if channel is 1 for opus and stereo=1, we fail.
1460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001461 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 cricket::AudioSendParameters parameters;
1463 parameters.codecs.push_back(kOpusCodec);
1464 parameters.codecs[0].bitrate = 0;
1465 parameters.codecs[0].channels = 1;
1466 parameters.codecs[0].params["stereo"] = "1";
1467 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468}
1469
ossu20a4b3f2017-04-27 02:08:52 -07001470// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001472 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 cricket::AudioSendParameters parameters;
1474 parameters.codecs.push_back(kOpusCodec);
1475 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001478}
1479
ossu20a4b3f2017-04-27 02:08:52 -07001480// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001482 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001483 cricket::AudioSendParameters parameters;
1484 parameters.codecs.push_back(kOpusCodec);
1485 parameters.codecs[0].bitrate = 0;
1486 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001487 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001488 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001489}
1490
ossu20a4b3f2017-04-27 02:08:52 -07001491// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001493 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001494 cricket::AudioSendParameters parameters;
1495 parameters.codecs.push_back(kOpusCodec);
1496 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001497 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001499 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001500 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001501
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001504 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001505}
1506
ossu20a4b3f2017-04-27 02:08:52 -07001507// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].bitrate = 0;
1513 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001514 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001515 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
ossu20a4b3f2017-04-27 02:08:52 -07001518// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 cricket::AudioSendParameters parameters;
1522 parameters.codecs.push_back(kOpusCodec);
1523 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001524 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001525 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001526 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001527 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001528
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001531 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001532}
1533
ossu20a4b3f2017-04-27 02:08:52 -07001534// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001541 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1542 EXPECT_EQ(111, spec.payload_type);
1543 EXPECT_EQ(96000, spec.target_bitrate_bps);
1544 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001545 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001546 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
ossu20a4b3f2017-04-27 02:08:52 -07001549// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001551 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 cricket::AudioSendParameters parameters;
1553 parameters.codecs.push_back(kOpusCodec);
1554 parameters.codecs[0].bitrate = 30000;
1555 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001557 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001558}
1559
ossu20a4b3f2017-04-27 02:08:52 -07001560// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001562 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001563 cricket::AudioSendParameters parameters;
1564 parameters.codecs.push_back(kOpusCodec);
1565 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001566 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001567 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001568}
1569
ossu20a4b3f2017-04-27 02:08:52 -07001570// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001571TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001572 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 cricket::AudioSendParameters parameters;
1574 parameters.codecs.push_back(kOpusCodec);
1575 parameters.codecs[0].bitrate = 30000;
1576 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001577 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001578 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001579}
1580
stefan13f1a0a2016-11-30 07:22:58 -08001581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1582 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1583 200000);
1584}
1585
1586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1587 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1588}
1589
1590TEST_F(WebRtcVoiceEngineTestFake,
1591 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1592 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1593}
1594
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1596 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1597}
1598
Yves Gerey665174f2018-06-19 15:03:05 +02001599TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001600 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1601 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001602 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001603 // Setting max bitrate should keep previous min bitrate
1604 // Setting max bitrate should not reset start bitrate.
1605 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1606 SetSdpBitrateParameters(
1607 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1608 Field(&BitrateConstraints::start_bitrate_bps, -1),
1609 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001610 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001611}
1612
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001613// Test that we can enable NACK with opus as caller.
1614TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001615 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001618 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1619 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001620 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623}
1624
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001625// Test that we can enable NACK with opus as callee.
1626TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001627 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001628 cricket::AudioSendParameters parameters;
1629 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001630 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1631 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001632 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001633 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001634 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001635 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001636
Yves Gerey665174f2018-06-19 15:03:05 +02001637 EXPECT_TRUE(
1638 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001639 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001640}
1641
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642// Test that we can enable NACK on receive streams.
1643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001644 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001645 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters parameters;
1647 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001648 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1649 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001650 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1651 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001652 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001653 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1654 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001655}
1656
1657// Test that we can disable NACK.
1658TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001659 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001660 cricket::AudioSendParameters parameters;
1661 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001662 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1663 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001665 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 parameters.codecs.clear();
1668 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001669 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001670 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671}
1672
1673// Test that we can disable NACK on receive streams.
1674TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001675 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001677 cricket::AudioSendParameters parameters;
1678 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001679 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1680 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001682 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1683 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 parameters.codecs.clear();
1686 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1689 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690}
1691
1692// Test that NACK is enabled on a new receive stream.
1693TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001694 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 cricket::AudioSendParameters parameters;
1696 parameters.codecs.push_back(kIsacCodec);
1697 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001698 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1699 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001700 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001701 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702
solenberg2100c0b2017-03-01 11:29:29 -08001703 EXPECT_TRUE(AddRecvStream(kSsrcY));
1704 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1705 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1706 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001707}
1708
stefanba4c0e42016-02-04 04:12:24 -08001709TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001711 cricket::AudioSendParameters send_parameters;
1712 send_parameters.codecs.push_back(kOpusCodec);
1713 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001715
1716 cricket::AudioRecvParameters recv_parameters;
1717 recv_parameters.codecs.push_back(kIsacCodec);
1718 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001719 EXPECT_TRUE(AddRecvStream(kSsrcX));
1720 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001721 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001722 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001723
ossudedfd282016-06-14 07:12:39 -07001724 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001726 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001727 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001728 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001729}
1730
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001731// Test that we can switch back and forth between Opus and ISAC with CN.
1732TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001733 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters opus_parameters;
1736 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001738 {
ossu20a4b3f2017-04-27 02:08:52 -07001739 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1740 EXPECT_EQ(111, spec.payload_type);
1741 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001742 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters isac_parameters;
1745 isac_parameters.codecs.push_back(kIsacCodec);
1746 isac_parameters.codecs.push_back(kCn16000Codec);
1747 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001749 {
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(103, spec.payload_type);
1752 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001753 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001754
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(opus_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(111, spec.payload_type);
1759 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001760 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001761}
1762
1763// Test that we handle various ways of specifying bitrate.
1764TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001765 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 cricket::AudioSendParameters parameters;
1767 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001768 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001769 {
ossu20a4b3f2017-04-27 02:08:52 -07001770 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1771 EXPECT_EQ(103, spec.payload_type);
1772 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1773 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001774 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775
Yves Gerey665174f2018-06-19 15:03:05 +02001776 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001778 {
ossu20a4b3f2017-04-27 02:08:52 -07001779 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1780 EXPECT_EQ(103, spec.payload_type);
1781 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1782 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001783 }
Yves Gerey665174f2018-06-19 15:03:05 +02001784 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001785 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001786 {
ossu20a4b3f2017-04-27 02:08:52 -07001787 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1788 EXPECT_EQ(103, spec.payload_type);
1789 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1790 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001791 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792
Yves Gerey665174f2018-06-19 15:03:05 +02001793 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001795 {
ossu20a4b3f2017-04-27 02:08:52 -07001796 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1797 EXPECT_EQ(0, spec.payload_type);
1798 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1799 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001800 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801
Yves Gerey665174f2018-06-19 15:03:05 +02001802 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001803 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001804 {
ossu20a4b3f2017-04-27 02:08:52 -07001805 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1806 EXPECT_EQ(0, spec.payload_type);
1807 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1808 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001809 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001812 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001813 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001814 {
ossu20a4b3f2017-04-27 02:08:52 -07001815 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1816 EXPECT_EQ(111, spec.payload_type);
1817 EXPECT_STREQ("opus", spec.format.name.c_str());
1818 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001819 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001820}
1821
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001822// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001823TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001824 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 cricket::AudioSendParameters parameters;
1826 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001827}
1828
1829// Test that we can set send codecs even with telephone-event codec as the first
1830// one on the list.
1831TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001832 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001834 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001835 parameters.codecs.push_back(kIsacCodec);
1836 parameters.codecs.push_back(kPcmuCodec);
1837 parameters.codecs[0].id = 98; // DTMF
1838 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001839 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001840 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1841 EXPECT_EQ(96, spec.payload_type);
1842 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001843 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001844 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001845}
1846
Harald Alvestranda1f66612018-02-21 11:24:23 +01001847// Test that CanInsertDtmf() is governed by the send flag
1848TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1849 EXPECT_TRUE(SetupSendStream());
1850 cricket::AudioSendParameters parameters;
1851 parameters.codecs.push_back(kTelephoneEventCodec1);
1852 parameters.codecs.push_back(kPcmuCodec);
1853 parameters.codecs[0].id = 98; // DTMF
1854 parameters.codecs[1].id = 96;
1855 SetSendParameters(parameters);
1856 EXPECT_FALSE(channel_->CanInsertDtmf());
1857 SetSend(true);
1858 EXPECT_TRUE(channel_->CanInsertDtmf());
1859 SetSend(false);
1860 EXPECT_FALSE(channel_->CanInsertDtmf());
1861}
1862
solenberg31642aa2016-03-14 08:00:37 -07001863// Test that payload type range is limited for telephone-event codec.
1864TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001865 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001866 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001867 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001868 parameters.codecs.push_back(kIsacCodec);
1869 parameters.codecs[0].id = 0; // DTMF
1870 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001871 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001872 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001873 EXPECT_TRUE(channel_->CanInsertDtmf());
1874 parameters.codecs[0].id = 128; // DTMF
1875 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1876 EXPECT_FALSE(channel_->CanInsertDtmf());
1877 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001878 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001879 EXPECT_TRUE(channel_->CanInsertDtmf());
1880 parameters.codecs[0].id = -1; // DTMF
1881 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1882 EXPECT_FALSE(channel_->CanInsertDtmf());
1883}
1884
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001885// Test that we can set send codecs even with CN codec as the first
1886// one on the list.
1887TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001888 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 cricket::AudioSendParameters parameters;
1890 parameters.codecs.push_back(kCn16000Codec);
1891 parameters.codecs.push_back(kIsacCodec);
1892 parameters.codecs.push_back(kPcmuCodec);
1893 parameters.codecs[0].id = 98; // wideband CN
1894 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001895 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001896 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1897 EXPECT_EQ(96, send_codec_spec.payload_type);
1898 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001899 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900}
1901
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001902// Test that we set VAD and DTMF types correctly as caller.
1903TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001904 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 cricket::AudioSendParameters parameters;
1906 parameters.codecs.push_back(kIsacCodec);
1907 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001908 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 parameters.codecs.push_back(kCn16000Codec);
1910 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001911 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001912 parameters.codecs[0].id = 96;
1913 parameters.codecs[2].id = 97; // wideband CN
1914 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001916 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1917 EXPECT_EQ(96, send_codec_spec.payload_type);
1918 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001919 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001920 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001921 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001922 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001923}
1924
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001925// Test that we set VAD and DTMF types correctly as callee.
1926TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001927 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 cricket::AudioSendParameters parameters;
1929 parameters.codecs.push_back(kIsacCodec);
1930 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001931 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 parameters.codecs.push_back(kCn16000Codec);
1933 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001934 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001935 parameters.codecs[0].id = 96;
1936 parameters.codecs[2].id = 97; // wideband CN
1937 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001938 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001939 EXPECT_TRUE(
1940 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001941
ossu20a4b3f2017-04-27 02:08:52 -07001942 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1943 EXPECT_EQ(96, send_codec_spec.payload_type);
1944 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001945 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001946 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001947 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001948 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001949}
1950
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001951// Test that we only apply VAD if we have a CN codec that matches the
1952// send codec clockrate.
1953TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001954 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001955 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001956 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 parameters.codecs.push_back(kIsacCodec);
1958 parameters.codecs.push_back(kCn16000Codec);
1959 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001961 {
ossu20a4b3f2017-04-27 02:08:52 -07001962 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1963 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001964 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001965 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001966 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001968 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001969 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001970 {
ossu20a4b3f2017-04-27 02:08:52 -07001971 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1972 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001973 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001974 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001975 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001978 {
ossu20a4b3f2017-04-27 02:08:52 -07001979 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1980 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001981 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001982 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001983 }
Brave Yao5225dd82015-03-26 07:39:19 +08001984 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001985 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001987 {
ossu20a4b3f2017-04-27 02:08:52 -07001988 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1989 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001990 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001991 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001992}
1993
1994// Test that we perform case-insensitive matching of codec names.
1995TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001996 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001997 cricket::AudioSendParameters parameters;
1998 parameters.codecs.push_back(kIsacCodec);
1999 parameters.codecs.push_back(kPcmuCodec);
2000 parameters.codecs.push_back(kCn16000Codec);
2001 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002002 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002003 parameters.codecs[0].name = "iSaC";
2004 parameters.codecs[0].id = 96;
2005 parameters.codecs[2].id = 97; // wideband CN
2006 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002007 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002008 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2009 EXPECT_EQ(96, send_codec_spec.payload_type);
2010 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002011 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002012 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002013 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002014 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002015}
2016
stefanba4c0e42016-02-04 04:12:24 -08002017class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2018 public:
2019 WebRtcVoiceEngineWithSendSideBweTest()
2020 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2021};
2022
2023TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2024 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002025 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002026 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002027 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2028 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2029 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002030 extension.id);
2031 return;
2032 }
2033 }
2034 FAIL() << "Transport sequence number extension not in header-extension list.";
2035}
2036
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002037// Test support for audio level header extension.
2038TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002039 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002040}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002041TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002042 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002043}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002044
solenbergd4adce42016-11-17 06:26:52 -08002045// Test support for transport sequence number header extension.
2046TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2047 TestSetSendRtpHeaderExtensions(
2048 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002049}
solenbergd4adce42016-11-17 06:26:52 -08002050TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2051 TestSetRecvRtpHeaderExtensions(
2052 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002053}
2054
solenberg1ac56142015-10-13 03:58:19 -07002055// Test that we can create a channel and start sending on it.
2056TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002057 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002058 SetSendParameters(send_parameters_);
2059 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002060 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002061 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002062 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002063}
2064
2065// Test that a channel will send if and only if it has a source and is enabled
2066// for sending.
2067TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002068 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002069 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002070 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002071 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002072 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2073 SetAudioSend(kSsrcX, true, &fake_source_);
2074 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2075 SetAudioSend(kSsrcX, true, nullptr);
2076 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002077}
2078
solenberg94218532016-06-16 10:53:22 -07002079// Test that a channel is muted/unmuted.
2080TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2081 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002082 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002083 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2084 SetAudioSend(kSsrcX, true, nullptr);
2085 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2086 SetAudioSend(kSsrcX, false, nullptr);
2087 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002088}
2089
solenberg6d6e7c52016-04-13 09:07:30 -07002090// Test that SetSendParameters() does not alter a stream's send state.
2091TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2092 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002093 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002094
2095 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002096 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002098
2099 // Changing RTP header extensions will recreate the AudioSendStream.
2100 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002101 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002102 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002103 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002104
2105 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002106 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002107 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002108
2109 // Changing RTP header extensions will recreate the AudioSendStream.
2110 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002111 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002113}
2114
solenberg1ac56142015-10-13 03:58:19 -07002115// Test that we can create a channel and start playing out on it.
2116TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002117 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002118 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002119 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002120 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002121 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002122 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002123}
2124
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125// Test that we can add and remove send streams.
2126TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2127 SetupForMultiSendStream();
2128
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002130 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131
solenbergc96df772015-10-21 13:01:53 -07002132 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002133 EXPECT_TRUE(
2134 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002135 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002137 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 }
tfarina5237aaf2015-11-10 23:44:30 -08002139 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140
solenbergc96df772015-10-21 13:01:53 -07002141 // Delete the send streams.
2142 for (uint32_t ssrc : kSsrcs4) {
2143 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002144 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002145 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 }
solenbergc96df772015-10-21 13:01:53 -07002147 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148}
2149
2150// Test SetSendCodecs correctly configure the codecs in all send streams.
2151TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2152 SetupForMultiSendStream();
2153
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002155 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002156 EXPECT_TRUE(
2157 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 }
2159
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002160 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002162 parameters.codecs.push_back(kIsacCodec);
2163 parameters.codecs.push_back(kCn16000Codec);
2164 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002165 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002166
2167 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002168 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002169 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2170 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002171 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2172 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002173 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002174 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175 }
2176
minyue7a973442016-10-20 03:27:12 -07002177 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002178 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002179 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002181 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2182 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002183 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2184 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002185 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002186 }
2187}
2188
2189// Test we can SetSend on all send streams correctly.
2190TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2191 SetupForMultiSendStream();
2192
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002193 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002194 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002195 EXPECT_TRUE(
2196 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002197 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002198 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002199 }
2200
2201 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002202 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002203 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002204 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002206 }
2207
2208 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002209 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002210 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002212 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 }
2214}
2215
2216// Test we can set the correct statistics on all send streams.
2217TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2218 SetupForMultiSendStream();
2219
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002221 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002222 EXPECT_TRUE(
2223 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 }
solenberg85a04962015-10-27 03:35:21 -07002225
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002226 // Create a receive stream to check that none of the send streams end up in
2227 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002228 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002229
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002230 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002231 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002232 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002233 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002234
solenberg85a04962015-10-27 03:35:21 -07002235 // Check stats for the added streams.
2236 {
2237 cricket::VoiceMediaInfo info;
2238 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002239
solenberg85a04962015-10-27 03:35:21 -07002240 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002241 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002242 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002243 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002244 }
hbos1acfbd22016-11-17 23:43:29 -08002245 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002246
2247 // We have added one receive stream. We should see empty stats.
2248 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002249 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002250 }
solenberg1ac56142015-10-13 03:58:19 -07002251
solenberg2100c0b2017-03-01 11:29:29 -08002252 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002253 {
2254 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002255 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002256 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002257 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002258 EXPECT_EQ(0u, info.receivers.size());
2259 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002260
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002261 // Deliver a new packet - a default receive stream should be created and we
2262 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002263 {
2264 cricket::VoiceMediaInfo info;
2265 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2266 SetAudioReceiveStreamStats();
2267 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002268 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002269 EXPECT_EQ(1u, info.receivers.size());
2270 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002271 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002272 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002273}
2274
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002275// Test that we can add and remove receive streams, and do proper send/playout.
2276// We can receive on multiple streams while sending one stream.
2277TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002278 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002279
solenberg1ac56142015-10-13 03:58:19 -07002280 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002281 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002282 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002283
solenberg1ac56142015-10-13 03:58:19 -07002284 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002286 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288
solenberg1ac56142015-10-13 03:58:19 -07002289 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002290 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291
2292 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002293 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2294 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2295 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002296
2297 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002298 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300
2301 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002302 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002303 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2304 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002305
aleloi84ef6152016-08-04 05:28:21 -07002306 // Restart playout and make sure recv streams are played out.
2307 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002308 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2309 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002310
aleloi84ef6152016-08-04 05:28:21 -07002311 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002312 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2313 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002314}
2315
wu@webrtc.org97077a32013-10-25 21:18:33 +00002316TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002317 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002318 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2319 .Times(1)
2320 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002321 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2322 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002323 send_parameters_.options.tx_agc_target_dbov = 3;
2324 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2325 send_parameters_.options.tx_agc_limiter = true;
2326 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002327 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2328 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2329 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002330 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002331}
2332
minyue6b825df2016-10-31 04:08:32 -07002333TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
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}
2341
2342TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2343 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002344 send_parameters_.options.audio_network_adaptor = true;
2345 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002346 SetSendParameters(send_parameters_);
2347 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002348 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002349 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002350 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002351 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002352 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002353}
2354
2355TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2356 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002357 send_parameters_.options.audio_network_adaptor = true;
2358 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002359 SetSendParameters(send_parameters_);
2360 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002361 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002362 const int initial_num = call_.GetNumCreatedSendStreams();
2363 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002364 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002365 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2366 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002367 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002368 // AudioSendStream not expected to be recreated.
2369 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2370 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002371 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002372}
2373
michaelt6672b262017-01-11 10:17:59 -08002374class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2375 : public WebRtcVoiceEngineTestFake {
2376 public:
2377 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2378 : WebRtcVoiceEngineTestFake(
2379 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2380 "Enabled/") {}
2381};
2382
2383TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2384 EXPECT_TRUE(SetupSendStream());
2385 cricket::AudioSendParameters parameters;
2386 parameters.codecs.push_back(kOpusCodec);
2387 SetSendParameters(parameters);
2388 const int initial_num = call_.GetNumCreatedSendStreams();
2389 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2390
2391 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2392 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002393 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2394 constexpr int kMinOverheadBps =
2395 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002396
2397 constexpr int kOpusMinBitrateBps = 6000;
2398 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002399 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002400 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002401 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002402 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002403
Oskar Sundbom78807582017-11-16 11:09:55 +01002404 parameters.options.audio_network_adaptor = true;
2405 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002406 SetSendParameters(parameters);
2407
ossu11bfc532017-02-16 05:37:06 -08002408 constexpr int kMinOverheadWithAnaBps =
2409 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002410
2411 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002412 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002413
minyuececec102017-03-27 13:04:25 -07002414 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002415 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002416}
2417
minyuececec102017-03-27 13:04:25 -07002418// This test is similar to
2419// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2420// additional field trial.
2421TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2422 SetRtpSendParameterUpdatesMaxBitrate) {
2423 EXPECT_TRUE(SetupSendStream());
2424 cricket::AudioSendParameters send_parameters;
2425 send_parameters.codecs.push_back(kOpusCodec);
2426 SetSendParameters(send_parameters);
2427
2428 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2429 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2430 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2431
2432 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002433 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002434 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002435
2436 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2437#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2438 constexpr int kMinOverhead = 3333;
2439#else
2440 constexpr int kMinOverhead = 6666;
2441#endif
2442 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2443}
2444
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002446// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002448 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002449 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450}
2451
2452TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2453 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002454 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002455 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002456 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002457 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002458 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002459 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002460 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461
solenberg85a04962015-10-27 03:35:21 -07002462 // Check stats for the added streams.
2463 {
2464 cricket::VoiceMediaInfo info;
2465 EXPECT_EQ(true, channel_->GetStats(&info));
2466
2467 // We have added one send stream. We should see the stats we've set.
2468 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002469 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002470 // We have added one receive stream. We should see empty stats.
2471 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002472 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002473 }
solenberg1ac56142015-10-13 03:58:19 -07002474
solenberg566ef242015-11-06 15:34:49 -08002475 // Start sending - this affects some reported stats.
2476 {
2477 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002478 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002479 EXPECT_EQ(true, channel_->GetStats(&info));
2480 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002481 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002482 }
2483
solenberg2100c0b2017-03-01 11:29:29 -08002484 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002485 {
2486 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002487 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002488 EXPECT_EQ(true, channel_->GetStats(&info));
2489 EXPECT_EQ(1u, info.senders.size());
2490 EXPECT_EQ(0u, info.receivers.size());
2491 }
solenberg1ac56142015-10-13 03:58:19 -07002492
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002493 // Deliver a new packet - a default receive stream should be created and we
2494 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002495 {
2496 cricket::VoiceMediaInfo info;
2497 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2498 SetAudioReceiveStreamStats();
2499 EXPECT_EQ(true, channel_->GetStats(&info));
2500 EXPECT_EQ(1u, info.senders.size());
2501 EXPECT_EQ(1u, info.receivers.size());
2502 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002503 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002504 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505}
2506
2507// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002508// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002510 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002511 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2512 EXPECT_TRUE(AddRecvStream(kSsrcY));
2513 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002514}
2515
2516// Test that the local SSRC is the same on sending and receiving channels if the
2517// receive channel is created before the send channel.
2518TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002519 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002520 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002521 EXPECT_TRUE(
2522 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002523 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2524 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002525}
2526
2527// Test that we can properly receive packets.
2528TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002529 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002530 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002532
Yves Gerey665174f2018-06-19 15:03:05 +02002533 EXPECT_TRUE(
2534 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535}
2536
2537// Test that we can properly receive packets on multiple streams.
2538TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002539 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002540 const uint32_t ssrc1 = 1;
2541 const uint32_t ssrc2 = 2;
2542 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002543 EXPECT_TRUE(AddRecvStream(ssrc1));
2544 EXPECT_TRUE(AddRecvStream(ssrc2));
2545 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002547 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002548 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002549 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002550 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002551 }
mflodman3d7db262016-04-29 00:57:13 -07002552
2553 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2554 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2555 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2556
2557 EXPECT_EQ(s1.received_packets(), 0);
2558 EXPECT_EQ(s2.received_packets(), 0);
2559 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002560
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002561 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002562 EXPECT_EQ(s1.received_packets(), 0);
2563 EXPECT_EQ(s2.received_packets(), 0);
2564 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002565
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002566 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002567 EXPECT_EQ(s1.received_packets(), 1);
2568 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2569 EXPECT_EQ(s2.received_packets(), 0);
2570 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002571
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002572 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002573 EXPECT_EQ(s1.received_packets(), 1);
2574 EXPECT_EQ(s2.received_packets(), 1);
2575 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2576 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002577
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002578 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002579 EXPECT_EQ(s1.received_packets(), 1);
2580 EXPECT_EQ(s2.received_packets(), 1);
2581 EXPECT_EQ(s3.received_packets(), 1);
2582 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002583
mflodman3d7db262016-04-29 00:57:13 -07002584 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2585 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2586 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002587}
2588
solenberg2100c0b2017-03-01 11:29:29 -08002589// Test that receiving on an unsignaled stream works (a stream is created).
2590TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002591 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002592 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002593
solenberg7e63ef02015-11-20 00:19:43 -08002594 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002595
Mirko Bonadeif859e552018-05-30 15:31:29 +02002596 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002597 EXPECT_TRUE(
2598 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002599}
2600
Seth Hampson5897a6e2018-04-03 11:16:33 -07002601// Tests that when we add a stream without SSRCs, but contains a stream_id
2602// that it is stored and its stream id is later used when the first packet
2603// arrives to properly create a receive stream with a sync label.
2604TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2605 const char kSyncLabel[] = "sync_label";
2606 EXPECT_TRUE(SetupChannel());
2607 cricket::StreamParams unsignaled_stream;
2608 unsignaled_stream.set_stream_ids({kSyncLabel});
2609 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2610 // The stream shouldn't have been created at this point because it doesn't
2611 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002612 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002613
2614 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2615
Mirko Bonadeif859e552018-05-30 15:31:29 +02002616 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002617 EXPECT_TRUE(
2618 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2619 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2620
2621 // Removing the unsignaled stream clears the cached parameters. If a new
2622 // default unsignaled receive stream is created it will not have a sync group.
2623 channel_->RemoveRecvStream(0);
2624 channel_->RemoveRecvStream(kSsrc1);
2625
2626 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2627
Mirko Bonadeif859e552018-05-30 15:31:29 +02002628 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002629 EXPECT_TRUE(
2630 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2631 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2632}
2633
solenberg2100c0b2017-03-01 11:29:29 -08002634// Test that receiving N unsignaled stream works (streams will be created), and
2635// that packets are forwarded to them all.
2636TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002637 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002638 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002639 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2640
solenberg2100c0b2017-03-01 11:29:29 -08002641 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002642 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002643 rtc::SetBE32(&packet[8], ssrc);
2644 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002645
solenberg2100c0b2017-03-01 11:29:29 -08002646 // Verify we have one new stream for each loop iteration.
2647 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002648 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2649 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002650 }
mflodman3d7db262016-04-29 00:57:13 -07002651
solenberg2100c0b2017-03-01 11:29:29 -08002652 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002653 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002654 rtc::SetBE32(&packet[8], ssrc);
2655 DeliverPacket(packet, sizeof(packet));
2656
solenbergebb349d2017-03-13 05:46:15 -07002657 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002658 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2659 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2660 }
2661
2662 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2663 constexpr uint32_t kAnotherSsrc = 667;
2664 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002665 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002666
2667 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002668 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002669 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002670 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002671 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2672 EXPECT_EQ(2, streams[i]->received_packets());
2673 }
2674 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2675 EXPECT_EQ(1, streams[i]->received_packets());
2676 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002677 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002678}
2679
solenberg2100c0b2017-03-01 11:29:29 -08002680// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002681// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002682TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002683 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002684 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002685 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2686
2687 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002688 const uint32_t signaled_ssrc = 1;
2689 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002690 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002691 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002692 EXPECT_TRUE(
2693 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002694 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002695
2696 // Note that the first unknown SSRC cannot be 0, because we only support
2697 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002698 const uint32_t unsignaled_ssrc = 7011;
2699 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002700 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002701 EXPECT_TRUE(
2702 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002703 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002704
2705 DeliverPacket(packet, sizeof(packet));
2706 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2707
2708 rtc::SetBE32(&packet[8], signaled_ssrc);
2709 DeliverPacket(packet, sizeof(packet));
2710 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002711 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002712}
2713
solenberg4904fb62017-02-17 12:01:14 -08002714// Two tests to verify that adding a receive stream with the same SSRC as a
2715// previously added unsignaled stream will only recreate underlying stream
2716// objects if the stream parameters have changed.
2717TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2718 EXPECT_TRUE(SetupChannel());
2719
2720 // Spawn unsignaled stream with SSRC=1.
2721 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002723 EXPECT_TRUE(
2724 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002725
2726 // Verify that the underlying stream object in Call is not recreated when a
2727 // stream with SSRC=1 is added.
2728 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002729 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002730 int audio_receive_stream_id = streams.front()->id();
2731 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002732 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002733 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2734}
2735
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2737 EXPECT_TRUE(SetupChannel());
2738
2739 // Spawn unsignaled stream with SSRC=1.
2740 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002741 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002742 EXPECT_TRUE(
2743 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002744
2745 // Verify that the underlying stream object in Call *is* recreated when a
2746 // stream with SSRC=1 is added, and which has changed stream parameters.
2747 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002748 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002749 int audio_receive_stream_id = streams.front()->id();
2750 cricket::StreamParams stream_params;
2751 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002752 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002753 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002754 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002755 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2756}
2757
solenberg1ac56142015-10-13 03:58:19 -07002758// Test that AddRecvStream creates new stream.
2759TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002760 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002761 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762}
2763
2764// Test that after adding a recv stream, we do not decode more codecs than
2765// those previously passed into SetRecvCodecs.
2766TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002768 cricket::AudioRecvParameters parameters;
2769 parameters.codecs.push_back(kIsacCodec);
2770 parameters.codecs.push_back(kPcmuCodec);
2771 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002772 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002773 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2774 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2775 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776}
2777
2778// Test that we properly clean up any streams that were added, even if
2779// not explicitly removed.
2780TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002781 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002783 EXPECT_TRUE(AddRecvStream(1));
2784 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002785
Mirko Bonadeif859e552018-05-30 15:31:29 +02002786 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2787 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788 delete channel_;
2789 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002790 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2791 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002792}
2793
wu@webrtc.org78187522013-10-07 23:32:02 +00002794TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002795 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002796 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002797}
2798
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002799TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002800 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002801 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002802 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002803}
2804
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002805// Test the InsertDtmf on default send stream as caller.
2806TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002807 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002808}
2809
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002810// Test the InsertDtmf on default send stream as callee
2811TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002812 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002813}
2814
2815// Test the InsertDtmf on specified send stream as caller.
2816TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002817 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002818}
2819
2820// Test the InsertDtmf on specified send stream as callee.
2821TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002822 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823}
2824
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002826 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002827 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002828 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2829 .Times(9)
2830 .WillRepeatedly(Return(false));
2831 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2832 .Times(4)
2833 .WillRepeatedly(Return(false));
2834 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2835 .Times(2)
2836 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002837
Mirko Bonadeif859e552018-05-30 15:31:29 +02002838 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002839 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840
solenberg246b8172015-12-08 09:50:23 -08002841 // Nothing set in AudioOptions, so everything should be as default.
2842 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002843 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002844 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002845 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002846 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002847 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848
2849 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002850 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002851 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002852 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // Turn echo cancellation back on, with settings, and make sure
2855 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002856 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002857 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002858 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002860 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2861 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002862 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002863 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002864 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002865
2866 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002867 send_parameters_.options.delay_agnostic_aec = false;
2868 send_parameters_.options.extended_filter_aec = false;
2869 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002870 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002871 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002872
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002873 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002874 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002875 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002876 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002877
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002879 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002880 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002881 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002882 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002883 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884
2885 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002886 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002888 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002889 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002890 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002892 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002893 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002894 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002895 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002896 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2897 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002898 send_parameters_.options.noise_suppression = false;
2899 send_parameters_.options.highpass_filter = false;
2900 send_parameters_.options.typing_detection = false;
2901 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002902 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002903 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002904 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905
solenberg1ac56142015-10-13 03:58:19 -07002906 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002907 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002908 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002909 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002910 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2911 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002912 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002913 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914}
2915
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002916TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002917 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002918 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2919 .Times(8)
2920 .WillRepeatedly(Return(false));
2921 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2922 .Times(8)
2923 .WillRepeatedly(Return(false));
2924 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2925 .Times(8)
2926 .WillRepeatedly(Return(false));
2927 EXPECT_CALL(adm_, RecordingIsInitialized())
2928 .Times(2)
2929 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002930 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2931 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002932 webrtc::AudioProcessing::Config apm_config;
2933 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002934 .WillRepeatedly(ReturnPointee(&apm_config));
2935 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002936 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002937 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002938
kwiberg686a8ef2016-02-26 03:00:35 -08002939 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002940 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002941 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2942 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002943 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002944 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002945 &call_, cricket::MediaConfig(), cricket::AudioOptions(),
2946 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947
2948 // Have to add a stream to make SetSend work.
2949 cricket::StreamParams stream1;
2950 stream1.ssrcs.push_back(1);
2951 channel1->AddSendStream(stream1);
2952 cricket::StreamParams stream2;
2953 stream2.ssrcs.push_back(2);
2954 channel2->AddSendStream(stream2);
2955
2956 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002957 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002958 parameters_options_all.options.echo_cancellation = true;
2959 parameters_options_all.options.auto_gain_control = true;
2960 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002961 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002962 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002963 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002964 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002965 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002966 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002967 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002968 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002969 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002970 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971
2972 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002973 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002974 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002975 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002976 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002977 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002978 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002979 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002980 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002981 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002982 expected_options.echo_cancellation = true;
2983 expected_options.auto_gain_control = true;
2984 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002985 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
2987 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002988 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002989 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002990 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002991 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002992 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002993 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002994 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002995 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01002996 expected_options.echo_cancellation = true;
2997 expected_options.auto_gain_control = false;
2998 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002999 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003001 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003002 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003003 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003004 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003005 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003006 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003007
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003008 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003009 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003010 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003011 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003012 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003013 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003015 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003016 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003017 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003018 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003019 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003020 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003023 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3024 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003025 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3026 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003027 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003028 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003029 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003030 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003031 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003032 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003033 expected_options.echo_cancellation = true;
3034 expected_options.auto_gain_control = false;
3035 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003036 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003037}
3038
wu@webrtc.orgde305012013-10-31 15:40:38 +00003039// This test verifies DSCP settings are properly applied on voice media channel.
3040TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003041 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003042 cricket::FakeNetworkInterface network_interface;
3043 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003044 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003045 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003046
peahb1c9d1d2017-07-25 15:45:24 -07003047 webrtc::AudioProcessing::Config apm_config;
3048 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003049 .WillRepeatedly(ReturnPointee(&apm_config));
3050 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003051 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003052 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003053
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003054 channel.reset(
3055 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3056 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003057 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003058 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3059 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3060
3061 config.enable_dscp = true;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003062 channel.reset(
3063 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3064 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003065 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003066 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3067
3068 // Create a send stream to configure
3069 EXPECT_TRUE(
3070 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3071 parameters = channel->GetRtpSendParameters(kSsrcZ);
3072 ASSERT_FALSE(parameters.encodings.empty());
3073
3074 // Various priorities map to various dscp values.
3075 parameters.encodings[0].network_priority = 4.0;
3076 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003077 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003078 parameters.encodings[0].network_priority = 0.5;
3079 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3080 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3081
3082 // A bad priority does not change the dscp value.
3083 parameters.encodings[0].network_priority = 0.0;
3084 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3085 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003086
Tim Haloun6ca98362018-09-17 17:06:08 -07003087 // Packets should also self-identify their dscp in PacketOptions.
3088 const uint8_t kData[10] = {0};
3089 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003090 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003091
nisse51542be2016-02-12 02:27:06 -08003092 // Verify that setting the option to false resets the
3093 // DiffServCodePoint.
3094 config.enable_dscp = false;
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003095 channel.reset(
3096 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
3097 &call_, config, cricket::AudioOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003098 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003099 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3100 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3101
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003102 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003103}
3104
solenberg4bac9c52015-10-09 02:32:53 -07003105TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003106 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003107 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003108 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003109 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003110 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003111 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3112 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3113 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003114}
3115
solenberg2100c0b2017-03-01 11:29:29 -08003116TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003117 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003118
3119 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003120 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003121 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3122
3123 // Should remember the volume "2" which will be set on new unsignaled streams,
3124 // and also set the gain to 2 on existing unsignaled streams.
3125 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3126 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3127
3128 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3129 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3130 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3131 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3132 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3133 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3134
3135 // Setting gain with SSRC=0 should affect all unsignaled streams.
3136 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003137 if (kMaxUnsignaledRecvStreams > 1) {
3138 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3139 }
solenberg2100c0b2017-03-01 11:29:29 -08003140 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3141
3142 // Setting gain on an individual stream affects only that.
3143 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003144 if (kMaxUnsignaledRecvStreams > 1) {
3145 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3146 }
solenberg2100c0b2017-03-01 11:29:29 -08003147 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148}
3149
Seth Hampson845e8782018-03-02 11:34:10 -08003150TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003151 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003152 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003153
solenbergff976312016-03-30 23:28:51 -07003154 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003155 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003156 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003157 // Creating two channels to make sure that sync label is set properly for both
3158 // the default voice channel and following ones.
3159 EXPECT_TRUE(channel_->AddRecvStream(sp));
3160 sp.ssrcs[0] += 1;
3161 EXPECT_TRUE(channel_->AddRecvStream(sp));
3162
Mirko Bonadeif859e552018-05-30 15:31:29 +02003163 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003164 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003165 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003166 << "SyncGroup should be set based on stream id";
3167 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003168 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003169 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003170}
3171
solenberg3a941542015-11-16 07:34:50 -08003172// TODO(solenberg): Remove, once recv streams are configured through Call.
3173// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003174TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003175 // Test that setting the header extensions results in the expected state
3176 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003177 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003178 ssrcs.push_back(223);
3179 ssrcs.push_back(224);
3180
solenbergff976312016-03-30 23:28:51 -07003181 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003182 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003183 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003184 EXPECT_TRUE(
3185 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003186 }
3187
Mirko Bonadeif859e552018-05-30 15:31:29 +02003188 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003189 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003190 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003191 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003192 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003193 }
3194
3195 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003196 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003197 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003198 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003199 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003200 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003201 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003202 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003203 EXPECT_NE(nullptr, s);
3204 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003205 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3206 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003207 for (const auto& s_ext : s_exts) {
3208 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003209 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003210 }
3211 }
3212 }
3213 }
3214
3215 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003216 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003217 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003218 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003219 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003220 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003221 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222}
3223
3224TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3225 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003226 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003227 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003228 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003229 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3230 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003232 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003233
solenbergff976312016-03-30 23:28:51 -07003234 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003235 cricket::WebRtcVoiceMediaChannel* media_channel =
3236 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003237 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003238 EXPECT_TRUE(media_channel->AddRecvStream(
3239 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3240
Mirko Bonadeif859e552018-05-30 15:31:29 +02003241 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003242 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003243 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244 EXPECT_EQ(0, s->received_packets());
3245 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3246 EXPECT_EQ(1, s->received_packets());
3247 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3248 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003249}
Minyue2013aec2015-05-13 14:14:42 +02003250
solenberg0a617e22015-10-20 15:49:38 -07003251// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003252// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003253TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003254 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003255 EXPECT_TRUE(AddRecvStream(kSsrcY));
3256 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003257 EXPECT_TRUE(
3258 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3260 EXPECT_TRUE(AddRecvStream(kSsrcW));
3261 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003262}
3263
solenberg7602aab2016-11-14 11:30:07 -08003264TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3265 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003267 EXPECT_TRUE(
3268 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003269 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3270 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3271 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003272 EXPECT_TRUE(
3273 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003274 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3275 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003276}
stefan658910c2015-09-03 05:48:32 -07003277
deadbeef884f5852016-01-15 09:20:04 -08003278TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003279 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003280 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3281 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003282
3283 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003284 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3285 EXPECT_TRUE(AddRecvStream(kSsrcX));
3286 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003287
3288 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003289 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3290 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003291
3292 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003293 channel_->SetRawAudioSink(kSsrcX, nullptr);
3294 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003295}
3296
solenberg2100c0b2017-03-01 11:29:29 -08003297TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003298 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003299 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3300 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003301 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3302 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003303
3304 // Should be able to set a default sink even when no stream exists.
3305 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3306
solenberg2100c0b2017-03-01 11:29:29 -08003307 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3308 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003309 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003310 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003311
3312 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003313 channel_->SetRawAudioSink(kSsrc0, nullptr);
3314 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003315
3316 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003317 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3318 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003319
3320 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003321 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003322 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003323 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3324
3325 // Spawn another unsignaled stream - it should be assigned the default sink
3326 // and the previous unsignaled stream should lose it.
3327 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3328 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3329 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3330 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003331 if (kMaxUnsignaledRecvStreams > 1) {
3332 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3333 }
solenberg2100c0b2017-03-01 11:29:29 -08003334 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3335
3336 // Reset the default sink - the second unsignaled stream should lose it.
3337 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003338 if (kMaxUnsignaledRecvStreams > 1) {
3339 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3340 }
solenberg2100c0b2017-03-01 11:29:29 -08003341 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3342
3343 // Try setting the default sink while two streams exists.
3344 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003345 if (kMaxUnsignaledRecvStreams > 1) {
3346 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3347 }
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3349
3350 // Try setting the sink for the first unsignaled stream using its known SSRC.
3351 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003352 if (kMaxUnsignaledRecvStreams > 1) {
3353 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3354 }
solenberg2100c0b2017-03-01 11:29:29 -08003355 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003356 if (kMaxUnsignaledRecvStreams > 1) {
3357 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3358 }
deadbeef884f5852016-01-15 09:20:04 -08003359}
3360
skvlad7a43d252016-03-22 15:32:27 -07003361// Test that, just like the video channel, the voice channel communicates the
3362// network state to the call.
3363TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003364 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003365
3366 EXPECT_EQ(webrtc::kNetworkUp,
3367 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3368 EXPECT_EQ(webrtc::kNetworkUp,
3369 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3370
3371 channel_->OnReadyToSend(false);
3372 EXPECT_EQ(webrtc::kNetworkDown,
3373 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3374 EXPECT_EQ(webrtc::kNetworkUp,
3375 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3376
3377 channel_->OnReadyToSend(true);
3378 EXPECT_EQ(webrtc::kNetworkUp,
3379 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3380 EXPECT_EQ(webrtc::kNetworkUp,
3381 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3382}
3383
aleloi18e0b672016-10-04 02:45:47 -07003384// Test that playout is still started after changing parameters
3385TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3386 SetupRecvStream();
3387 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003388 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003389
3390 // Changing RTP header extensions will recreate the AudioReceiveStream.
3391 cricket::AudioRecvParameters parameters;
3392 parameters.extensions.push_back(
3393 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3394 channel_->SetRecvParameters(parameters);
3395
solenberg2100c0b2017-03-01 11:29:29 -08003396 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003397}
3398
Zhi Huangfa266ef2017-12-13 10:27:46 -08003399// Tests when GetSources is called with non-existing ssrc, it will return an
3400// empty list of RtpSource without crashing.
3401TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3402 // Setup an recv stream with |kSsrcX|.
3403 SetupRecvStream();
3404 cricket::WebRtcVoiceMediaChannel* media_channel =
3405 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3406 // Call GetSources with |kSsrcY| which doesn't exist.
3407 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3408 EXPECT_EQ(0u, sources.size());
3409}
3410
stefan658910c2015-09-03 05:48:32 -07003411// Tests that the library initializes and shuts down properly.
3412TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003413 // If the VoiceEngine wants to gather available codecs early, that's fine but
3414 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003415 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003416 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003417 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003418 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003419 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003420 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003421 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003422 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003423 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003424 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003425 cricket::VoiceMediaChannel* channel =
3426 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3427 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003428 EXPECT_TRUE(channel != nullptr);
3429 delete channel;
solenbergff976312016-03-30 23:28:51 -07003430}
stefan658910c2015-09-03 05:48:32 -07003431
solenbergff976312016-03-30 23:28:51 -07003432// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003433TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3434 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003435 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003436 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003437 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003438 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003439 {
peaha9cc40b2017-06-29 08:32:09 -07003440 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003441 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003442 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003443 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003444 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003445 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003446 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003447 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003448 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003449 cricket::VoiceMediaChannel* channel =
3450 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3451 cricket::AudioOptions(), webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003452 EXPECT_TRUE(channel != nullptr);
3453 delete channel;
3454 }
stefan658910c2015-09-03 05:48:32 -07003455}
3456
ossu20a4b3f2017-04-27 02:08:52 -07003457// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3458TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003459 // TODO(ossu): Why are the payload types of codecs with non-static payload
3460 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003461 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003462 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003463 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003464 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003465 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003466 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003467 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003468 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003469 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3470 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3471 (clockrate == 0 || codec.clockrate == clockrate);
3472 };
3473 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003474 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003475 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003476 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003477 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003478 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003479 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003480 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003481 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003482 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003483 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003484 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003485 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3486 // Remove these checks once both send and receive side assigns payload
3487 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003488 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003489 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003490 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003491 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003492 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003493 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003494 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003495 EXPECT_EQ(111, codec.id);
3496 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3497 EXPECT_EQ("10", codec.params.find("minptime")->second);
3498 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3499 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003500 }
3501 }
stefan658910c2015-09-03 05:48:32 -07003502}
3503
3504// Tests that VoE supports at least 32 channels
3505TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003506 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003507 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003508 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003509 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003510 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003511 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003512 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003513 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003514 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003515 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003516
3517 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003518 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003519 while (num_channels < arraysize(channels)) {
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003520 cricket::VoiceMediaChannel* channel =
3521 engine.CreateChannel(call.get(), cricket::MediaConfig(),
3522 cricket::AudioOptions(), webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003523 if (!channel)
3524 break;
stefan658910c2015-09-03 05:48:32 -07003525 channels[num_channels++] = channel;
3526 }
3527
Mirko Bonadeif859e552018-05-30 15:31:29 +02003528 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003529 EXPECT_EQ(expected, num_channels);
3530
3531 while (num_channels > 0) {
3532 delete channels[--num_channels];
3533 }
stefan658910c2015-09-03 05:48:32 -07003534}
3535
3536// Test that we set our preferred codecs properly.
3537TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003538 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3539 // - Check that our builtin codecs are usable by Channel.
3540 // - The codecs provided by the engine is usable by Channel.
3541 // It does not check that the codecs in the RecvParameters are actually
3542 // what we sent in - though it's probably reasonable to expect so, if
3543 // SetRecvParameters returns true.
3544 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003545 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003546 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003547 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003548 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003549 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003550 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003551 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003552 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003553 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003554 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003555 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003556 cricket::AudioOptions(),
3557 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003558 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003559 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003560 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003561}
ossu9def8002017-02-09 05:14:32 -08003562
3563TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3564 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003565 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3566 {48000, 2, 16000, 10000, 20000}};
3567 spec1.info.allow_comfort_noise = false;
3568 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003569 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003570 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3571 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003572 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003573 specs.push_back(webrtc::AudioCodecSpec{
3574 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3575 {16000, 1, 13300}});
3576 specs.push_back(
3577 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3578 specs.push_back(
3579 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003580
ossueb1fde42017-05-02 06:46:30 -07003581 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3582 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3583 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003584 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003585 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003586 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003587 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003588
peaha9cc40b2017-06-29 08:32:09 -07003589 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003590 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003591 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003592 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003593 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003594 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003595 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003596
3597 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3598 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003599 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3600 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3601 if (codecs.size() > index)
3602 return codecs[index];
3603 return missing_codec;
3604 };
ossu9def8002017-02-09 05:14:32 -08003605
3606 // Ensure the general codecs are generated first and in order.
3607 for (size_t i = 0; i != specs.size(); ++i) {
3608 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3609 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3610 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3611 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3612 }
3613
3614 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003615 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003616 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3617 for (size_t i = 0; i != codecs.size(); ++i) {
3618 const cricket::AudioCodec& codec = codecs[i];
3619 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3620 codec.clockrate == format.clockrate_hz &&
3621 codec.channels == format.num_channels) {
3622 return rtc::checked_cast<int>(i);
3623 }
3624 }
3625 return -1;
3626 };
ossu9def8002017-02-09 05:14:32 -08003627
3628 // Ensure all supplementary codecs are generated last. Their internal ordering
3629 // is not important.
3630 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3631 const int num_specs = static_cast<int>(specs.size());
3632 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3633 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3634 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3635 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3636 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3637 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3638 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3639}