blob: 53c4393e33932ae4cdcf426dac5f8792663b11dd [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);
solenberg2779bab2016-11-17 04:45:19 -080057const cricket::AudioCodec
58 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
59const cricket::AudioCodec
60 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
61
solenberg2100c0b2017-03-01 11:29:29 -080062const uint32_t kSsrc0 = 0;
63const uint32_t kSsrc1 = 1;
64const uint32_t kSsrcX = 0x99;
65const uint32_t kSsrcY = 0x17;
66const uint32_t kSsrcZ = 0x42;
67const uint32_t kSsrcW = 0x02;
68const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
solenberg971cab02016-06-14 10:02:41 -070070constexpr int kRtpHistoryMs = 5000;
71
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010072constexpr webrtc::GainControl::Mode kDefaultAgcMode =
73#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
74 webrtc::GainControl::kFixedDigital;
75#else
76 webrtc::GainControl::kAdaptiveAnalog;
77#endif
78
79constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
80 webrtc::NoiseSuppression::kHigh;
81
solenberg9a5f032222017-03-15 06:14:12 -070082void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
83 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010084
85 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010086 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010087 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010088 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070089#if defined(WEBRTC_WIN)
90 EXPECT_CALL(*adm, SetPlayoutDevice(
91 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
92 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
93 .WillOnce(Return(0));
94#else
95 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
96#endif // #if defined(WEBRTC_WIN)
97 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
98 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
99 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100100#if defined(WEBRTC_WIN)
101 EXPECT_CALL(*adm, SetRecordingDevice(
102 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
103 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
104 .WillOnce(Return(0));
105#else
106 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
107#endif // #if defined(WEBRTC_WIN)
108 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
109 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
110 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700111 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114
115 // Teardown.
116 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
118 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
119 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100120 EXPECT_CALL(*adm, Release()).Times(3)
121 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700122}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200123} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124
solenbergff976312016-03-30 23:28:51 -0700125// Tests that our stub library "works".
126TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700127 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700128 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700129 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
130 new rtc::RefCountedObject<
131 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700132 webrtc::AudioProcessing::Config apm_config;
133 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
134 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700135 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700136 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700137 {
ossuc54071d2016-08-17 02:45:41 -0700138 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700139 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100140 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700141 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700142 }
solenbergff976312016-03-30 23:28:51 -0700143}
144
deadbeef884f5852016-01-15 09:20:04 -0800145class FakeAudioSink : public webrtc::AudioSinkInterface {
146 public:
147 void OnData(const Data& audio) override {}
148};
149
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800150class FakeAudioSource : public cricket::AudioSource {
151 void SetSink(Sink* sink) override {}
152};
153
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154class WebRtcVoiceEngineTestFake : public testing::Test {
155 public:
stefanba4c0e42016-02-04 04:12:24 -0800156 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
157
158 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700159 : apm_(new rtc::RefCountedObject<
160 StrictMock<webrtc::test::MockAudioProcessing>>()),
161 apm_gc_(*apm_->gain_control()),
162 apm_ec_(*apm_->echo_cancellation()),
163 apm_ns_(*apm_->noise_suppression()),
164 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100165 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700166 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800167 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700168 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800169 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700170 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
171 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700172 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700173 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800174 // Default Options.
175 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
176 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100177 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
178 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800179 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100180 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
181 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800182 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
183 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800184 // Init does not overwrite default AGC config.
185 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
186 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
187 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800188 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
189 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700190 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800191 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700192 // factories. Those tests should probably be moved elsewhere.
193 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
194 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100195 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100196 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700197 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200198 send_parameters_.codecs.push_back(kPcmuCodec);
199 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100200
solenberg76377c52017-02-21 00:54:31 -0800201 // Default Options.
202 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 }
solenberg8189b022016-06-14 12:13:00 -0700204
solenbergff976312016-03-30 23:28:51 -0700205 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700206 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700207 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
208 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200209 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupRecvStream() {
213 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700214 return false;
215 }
solenberg2100c0b2017-03-01 11:29:29 -0800216 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200220 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
221 }
222
223 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700224 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000225 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 }
Florent Castellidacec712018-05-24 16:24:21 +0200227 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800228 return false;
229 }
peaha9cc40b2017-06-29 08:32:09 -0700230 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800231 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
234 bool AddRecvStream(uint32_t ssrc) {
235 EXPECT_TRUE(channel_);
236 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
237 }
238
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000239 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700240 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700241 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800242 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
243 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700244 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800245 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246 }
solenberg8189b022016-06-14 12:13:00 -0700247
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700249 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 }
solenberg8189b022016-06-14 12:13:00 -0700252
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200253 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 }
256
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100257 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
258 const auto* send_stream = call_.GetAudioSendStream(ssrc);
259 EXPECT_TRUE(send_stream);
260 return *send_stream;
261 }
262
deadbeef884f5852016-01-15 09:20:04 -0800263 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
264 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
265 EXPECT_TRUE(recv_stream);
266 return *recv_stream;
267 }
268
solenberg3a941542015-11-16 07:34:50 -0800269 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800270 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800271 }
272
solenberg7add0582015-11-20 09:59:34 -0800273 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800274 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800275 }
276
solenberg059fb442016-10-26 05:12:24 -0700277 void SetSend(bool enable) {
278 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700279 if (enable) {
280 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
281 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
282 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700283 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700284 }
solenberg059fb442016-10-26 05:12:24 -0700285 channel_->SetSend(enable);
286 }
287
288 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700289 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700290 ASSERT_TRUE(channel_);
291 EXPECT_TRUE(channel_->SetSendParameters(params));
292 }
293
minyue6b825df2016-10-31 04:08:32 -0700294 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
295 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700296 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700297 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700298 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700299 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700300 }
301 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700302 }
303
solenbergffbbcac2016-11-17 05:25:37 -0800304 void TestInsertDtmf(uint32_t ssrc, bool caller,
305 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700306 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000307 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700308 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000309 // send stream.
310 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800311 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700315 SetSendParameters(send_parameters_);
316 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800318 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800319 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700320 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322
323 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700324 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800325 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800327 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328 }
329
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100333 // Test send.
334 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800335 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100336 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800337 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800338 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800339 EXPECT_EQ(codec.id, telephone_event.payload_type);
340 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 EXPECT_EQ(2, telephone_event.event_code);
342 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 }
344
345 // Test that send bandwidth is set correctly.
346 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000347 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
348 // |expected_result| is the expected result from SetMaxSendBandwidth().
349 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700350 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
351 int max_bitrate,
352 bool expected_result,
353 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200354 cricket::AudioSendParameters parameters;
355 parameters.codecs.push_back(codec);
356 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700357 if (expected_result) {
358 SetSendParameters(parameters);
359 } else {
360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
361 }
solenberg2100c0b2017-03-01 11:29:29 -0800362 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 }
364
skvlade0d46372016-04-07 22:59:22 -0700365 // Sets the per-stream maximum bitrate limit for the specified SSRC.
366 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700367 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700368 EXPECT_EQ(1UL, parameters.encodings.size());
369
Oskar Sundbom78807582017-11-16 11:09:55 +0100370 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800371 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700372 }
373
solenberg059fb442016-10-26 05:12:24 -0700374 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700375 cricket::AudioSendParameters send_parameters;
376 send_parameters.codecs.push_back(codec);
377 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700378 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700379 }
380
ossu20a4b3f2017-04-27 02:08:52 -0700381 void CheckSendCodecBitrate(int32_t ssrc,
382 const char expected_name[],
383 int expected_bitrate) {
384 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
385 EXPECT_EQ(expected_name, spec->format.name);
386 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700387 }
388
ossu20a4b3f2017-04-27 02:08:52 -0700389 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
390 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700391 }
392
minyue6b825df2016-10-31 04:08:32 -0700393 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
394 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
395 }
396
skvlade0d46372016-04-07 22:59:22 -0700397 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
398 int global_max,
399 int stream_max,
400 bool expected_result,
401 int expected_codec_bitrate) {
402 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800403 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700404
405 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700406 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800407 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700408
409 // Verify that reading back the parameters gives results
410 // consistent with the Set() result.
411 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800412 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700413 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
414 EXPECT_EQ(expected_result ? stream_max : -1,
415 resulting_parameters.encodings[0].max_bitrate_bps);
416
417 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800418 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700419 }
420
stefan13f1a0a2016-11-30 07:22:58 -0800421 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
422 int expected_min_bitrate_bps,
423 const char* start_bitrate_kbps,
424 int expected_start_bitrate_bps,
425 const char* max_bitrate_kbps,
426 int expected_max_bitrate_bps) {
427 EXPECT_TRUE(SetupSendStream());
428 auto& codecs = send_parameters_.codecs;
429 codecs.clear();
430 codecs.push_back(kOpusCodec);
431 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
432 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
433 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100434 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
435 SetSdpBitrateParameters(
436 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
437 expected_min_bitrate_bps),
438 Field(&BitrateConstraints::start_bitrate_bps,
439 expected_start_bitrate_bps),
440 Field(&BitrateConstraints::max_bitrate_bps,
441 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800442
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100443 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100536 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100541 stats.apm_statistics.delay_median_ms = 234;
542 stats.apm_statistics.delay_standard_deviation_ms = 567;
543 stats.apm_statistics.echo_return_loss = 890;
544 stats.apm_statistics.echo_return_loss_enhancement = 1234;
545 stats.apm_statistics.residual_echo_likelihood = 0.432f;
546 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100547 stats.ana_statistics.bitrate_action_counter = 321;
548 stats.ana_statistics.channel_action_counter = 432;
549 stats.ana_statistics.dtx_action_counter = 543;
550 stats.ana_statistics.fec_action_counter = 654;
551 stats.ana_statistics.frame_length_increase_counter = 765;
552 stats.ana_statistics.frame_length_decrease_counter = 876;
553 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700554 stats.typing_noise_detected = true;
555 return stats;
556 }
557 void SetAudioSendStreamStats() {
558 for (auto* s : call_.GetAudioSendStreams()) {
559 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200560 }
solenberg85a04962015-10-27 03:35:21 -0700561 }
solenberg566ef242015-11-06 15:34:49 -0800562 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
563 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700564 const auto stats = GetAudioSendStreamStats();
565 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
566 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
567 EXPECT_EQ(info.packets_sent, stats.packets_sent);
568 EXPECT_EQ(info.packets_lost, stats.packets_lost);
569 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
570 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800571 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700572 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
573 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
574 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
575 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100576 EXPECT_EQ(info.apm_statistics.delay_median_ms,
577 stats.apm_statistics.delay_median_ms);
578 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
579 stats.apm_statistics.delay_standard_deviation_ms);
580 EXPECT_EQ(info.apm_statistics.echo_return_loss,
581 stats.apm_statistics.echo_return_loss);
582 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
583 stats.apm_statistics.echo_return_loss_enhancement);
584 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
585 stats.apm_statistics.residual_echo_likelihood);
586 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
587 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700588 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
589 stats.ana_statistics.bitrate_action_counter);
590 EXPECT_EQ(info.ana_statistics.channel_action_counter,
591 stats.ana_statistics.channel_action_counter);
592 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
593 stats.ana_statistics.dtx_action_counter);
594 EXPECT_EQ(info.ana_statistics.fec_action_counter,
595 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700596 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
597 stats.ana_statistics.frame_length_increase_counter);
598 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
599 stats.ana_statistics.frame_length_decrease_counter);
600 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
601 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800602 EXPECT_EQ(info.typing_noise_detected,
603 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700604 }
605
606 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
607 webrtc::AudioReceiveStream::Stats stats;
608 stats.remote_ssrc = 123;
609 stats.bytes_rcvd = 456;
610 stats.packets_rcvd = 768;
611 stats.packets_lost = 101;
612 stats.fraction_lost = 23.45f;
613 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100614 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700615 stats.ext_seqnum = 678;
616 stats.jitter_ms = 901;
617 stats.jitter_buffer_ms = 234;
618 stats.jitter_buffer_preferred_ms = 567;
619 stats.delay_estimate_ms = 890;
620 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700621 stats.total_samples_received = 5678901;
622 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200623 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200624 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700625 stats.expand_rate = 5.67f;
626 stats.speech_expand_rate = 8.90f;
627 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200628 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700629 stats.accelerate_rate = 4.56f;
630 stats.preemptive_expand_rate = 7.89f;
631 stats.decoding_calls_to_silence_generator = 12;
632 stats.decoding_calls_to_neteq = 345;
633 stats.decoding_normal = 67890;
634 stats.decoding_plc = 1234;
635 stats.decoding_cng = 5678;
636 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700637 stats.decoding_muted_output = 3456;
638 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 return stats;
640 }
641 void SetAudioReceiveStreamStats() {
642 for (auto* s : call_.GetAudioReceiveStreams()) {
643 s->SetStats(GetAudioReceiveStreamStats());
644 }
645 }
646 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700647 const auto stats = GetAudioReceiveStreamStats();
648 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
649 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200650 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
651 stats.packets_rcvd);
652 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
653 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700654 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
655 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800656 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200657 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
658 stats.ext_seqnum);
659 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
660 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
661 stats.jitter_buffer_ms);
662 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700663 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200664 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
665 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700666 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700667 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
668 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200669 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200670 EXPECT_EQ(info.jitter_buffer_delay_seconds,
671 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700672 EXPECT_EQ(info.expand_rate, stats.expand_rate);
673 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
674 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200675 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700676 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
677 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200678 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700679 stats.decoding_calls_to_silence_generator);
680 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
681 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
682 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
683 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
684 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700685 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700686 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200687 }
hbos1acfbd22016-11-17 23:43:29 -0800688 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
689 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
690 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
691 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
692 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
693 codec.ToCodecParameters());
694 }
695 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
696 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
697 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
698 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
699 codec.ToCodecParameters());
700 }
701 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200702
peah8271d042016-11-22 07:24:52 -0800703 bool IsHighPassFilterEnabled() {
704 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
705 }
706
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700708 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700709 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800710 webrtc::test::MockGainControl& apm_gc_;
711 webrtc::test::MockEchoCancellation& apm_ec_;
712 webrtc::test::MockNoiseSuppression& apm_ns_;
713 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200714 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700715 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700716 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200717 cricket::AudioSendParameters send_parameters_;
718 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800719 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700720 webrtc::AudioProcessing::Config apm_config_;
721
stefanba4c0e42016-02-04 04:12:24 -0800722 private:
723 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724};
725
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726// Tests that we can create and destroy a channel.
727TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700728 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729}
730
solenberg31fec402016-05-06 02:13:12 -0700731// Test that we can add a send stream and that it has the correct defaults.
732TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
733 EXPECT_TRUE(SetupChannel());
734 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800735 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
736 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
737 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700738 EXPECT_EQ("", config.rtp.c_name);
739 EXPECT_EQ(0u, config.rtp.extensions.size());
740 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
741 config.send_transport);
742}
743
744// Test that we can add a receive stream and that it has the correct defaults.
745TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
746 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800747 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700748 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800749 GetRecvStreamConfig(kSsrcX);
750 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700751 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
752 EXPECT_FALSE(config.rtp.transport_cc);
753 EXPECT_EQ(0u, config.rtp.extensions.size());
754 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
755 config.rtcp_send_transport);
756 EXPECT_EQ("", config.sync_group);
757}
758
stefanba4c0e42016-02-04 04:12:24 -0800759TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700760 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800761 bool opus_found = false;
762 for (cricket::AudioCodec codec : codecs) {
763 if (codec.name == "opus") {
764 EXPECT_TRUE(HasTransportCc(codec));
765 opus_found = true;
766 }
767 }
768 EXPECT_TRUE(opus_found);
769}
770
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771// Test that we set our inbound codecs properly, including changing PT.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800777 parameters.codecs.push_back(kTelephoneEventCodec1);
778 parameters.codecs.push_back(kTelephoneEventCodec2);
779 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200780 parameters.codecs[2].id = 126;
781 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800782 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700783 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
784 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
785 {{0, {"PCMU", 8000, 1}},
786 {106, {"ISAC", 16000, 1}},
787 {126, {"telephone-event", 8000, 1}},
788 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail to set an unknown inbound codec.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700796 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798}
799
800// Test that we fail if we have duplicate types in the inbound list.
801TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700802 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200803 cricket::AudioRecvParameters parameters;
804 parameters.codecs.push_back(kIsacCodec);
805 parameters.codecs.push_back(kCn16000Codec);
806 parameters.codecs[1].id = kIsacCodec.id;
807 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that we can decode OPUS without stereo parameters.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
816 parameters.codecs.push_back(kOpusCodec);
817 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800818 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700819 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
820 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
821 {{0, {"PCMU", 8000, 1}},
822 {103, {"ISAC", 16000, 1}},
823 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS with stereo = 0.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 parameters.codecs[2].params["stereo"] = "0";
834 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800835 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700836 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
837 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
838 {{0, {"PCMU", 8000, 1}},
839 {103, {"ISAC", 16000, 1}},
840 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can decode OPUS with stereo = 1.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kPcmuCodec);
849 parameters.codecs.push_back(kOpusCodec);
850 parameters.codecs[2].params["stereo"] = "1";
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700853 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
854 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
855 {{0, {"PCMU", 8000, 1}},
856 {103, {"ISAC", 16000, 1}},
857 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that changes to recv codecs are applied to all streams.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800866 parameters.codecs.push_back(kTelephoneEventCodec1);
867 parameters.codecs.push_back(kTelephoneEventCodec2);
868 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200869 parameters.codecs[2].id = 126;
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700871 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
872 EXPECT_TRUE(AddRecvStream(ssrc));
873 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
874 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
875 {{0, {"PCMU", 8000, 1}},
876 {106, {"ISAC", 16000, 1}},
877 {126, {"telephone-event", 8000, 1}},
878 {107, {"telephone-event", 32000, 1}}})));
879 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800886 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
solenberg2100c0b2017-03-01 11:29:29 -0800889 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200890 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800891 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894// Test that we can apply the same set of codecs again while playing.
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
899 parameters.codecs.push_back(kCn16000Codec);
900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700901 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
deadbeefcb383672017-04-26 16:28:42 -0700904 // Remapping a payload type to a different codec should fail.
905 parameters.codecs[0] = kOpusCodec;
906 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800908 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can add a codec while playing.
912TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kCn16000Codec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700918 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 parameters.codecs.push_back(kOpusCodec);
921 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800922 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
deadbeefcb383672017-04-26 16:28:42 -0700925// Test that we accept adding the same codec with a different payload type.
926// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
927TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
928 EXPECT_TRUE(SetupRecvStream());
929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932
933 ++parameters.codecs[0].id;
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
935}
936
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 // Test that when autobw is enabled, bitrate is kept as the default
941 // value. autobw is enabled for the following tests because the target
942 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
947 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700948 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
ossu20a4b3f2017-04-27 02:08:52 -0700950 // opus, default bitrate == 32000 in mono.
951 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
959 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700960 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
964 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
965 // Rates above the max (510000) should be capped.
966 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971
972 // Test that we can only set a maximum bitrate for a fixed-rate codec
973 // if it's bigger than the fixed rate.
974
975 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983}
984
985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 const int kDesiredBitrate = 128000;
988 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700989 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200990 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700991 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
993 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800994 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000995
solenberg2100c0b2017-03-01 11:29:29 -0800996 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000997}
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999// Test that bitrate cannot be set for CBR codecs.
1000// Bitrate is ignored if it is higher than the fixed bitrate.
1001// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008
1009 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001010 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001012
1013 send_parameters_.max_bandwidth_bps = 128;
1014 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016}
1017
skvlade0d46372016-04-07 22:59:22 -07001018// Test that the per-stream bitrate limit and the global
1019// bitrate limit both apply.
1020TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1021 EXPECT_TRUE(SetupSendStream());
1022
ossu20a4b3f2017-04-27 02:08:52 -07001023 // opus, default bitrate == 32000.
1024 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001025 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1028
1029 // CBR codecs allow both maximums to exceed the bitrate.
1030 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1031 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1034
1035 // CBR codecs don't allow per stream maximums to be too low.
1036 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1037 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1038}
1039
1040// Test that an attempt to set RtpParameters for a stream that does not exist
1041// fails.
1042TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1043 EXPECT_TRUE(SetupChannel());
1044 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001045 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001046 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001047
1048 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001049 EXPECT_FALSE(
1050 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001051}
1052
1053TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001054 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001055 // This test verifies that setting RtpParameters succeeds only if
1056 // the structure contains exactly one encoding.
1057 // TODO(skvlad): Update this test when we start supporting setting parameters
1058 // for each encoding individually.
1059
1060 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001061 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001062 // Two or more encodings should result in failure.
1063 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001064 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001065 // Zero encodings should also fail.
1066 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001067 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001068}
1069
1070// Changing the SSRC through RtpParameters is not allowed.
1071TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1072 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001074 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001076}
1077
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001078// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001079// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1081 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001082 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001084 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001085 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086 ASSERT_EQ(1u, parameters.encodings.size());
1087 ASSERT_TRUE(parameters.encodings[0].active);
1088 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001089 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091
1092 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001093 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001095 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001096 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001097 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098}
1099
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001100// Test that SetRtpSendParameters configures the correct encoding channel for
1101// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001102TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1103 SetupForMultiSendStream();
1104 // Create send streams.
1105 for (uint32_t ssrc : kSsrcs4) {
1106 EXPECT_TRUE(
1107 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1108 }
1109 // Configure one stream to be limited by the stream config, another to be
1110 // limited by the global max, and the third one with no per-stream limit
1111 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001112 SetGlobalMaxBitrate(kOpusCodec, 32000);
1113 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1114 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001115 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1116
ossu20a4b3f2017-04-27 02:08:52 -07001117 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1118 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1119 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001120
1121 // Remove the global cap; the streams should switch to their respective
1122 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001123 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001124 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1125 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1126 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001127}
1128
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001129// Test that GetRtpSendParameters returns the currently configured codecs.
1130TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131 EXPECT_TRUE(SetupSendStream());
1132 cricket::AudioSendParameters parameters;
1133 parameters.codecs.push_back(kIsacCodec);
1134 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001135 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001136
solenberg2100c0b2017-03-01 11:29:29 -08001137 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1140 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001141}
1142
Florent Castellidacec712018-05-24 16:24:21 +02001143// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1144TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1145 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1146 params.cname = "rtcpcname";
1147 EXPECT_TRUE(SetupSendStream(params));
1148
1149 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1150 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1151}
1152
Florent Castelliabe301f2018-06-12 18:33:49 +02001153TEST_F(WebRtcVoiceEngineTestFake,
1154 DetectRtpSendParameterHeaderExtensionsChange) {
1155 EXPECT_TRUE(SetupSendStream());
1156
1157 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1158 rtp_parameters.header_extensions.emplace_back();
1159
1160 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1161
1162 webrtc::RTCError result =
1163 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1164 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1165}
1166
deadbeefcb443432016-12-12 11:12:36 -08001167// Test that GetRtpSendParameters returns an SSRC.
1168TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1169 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001170 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001171 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001172 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001173}
1174
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001176TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001177 EXPECT_TRUE(SetupSendStream());
1178 cricket::AudioSendParameters parameters;
1179 parameters.codecs.push_back(kIsacCodec);
1180 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001181 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001182
solenberg2100c0b2017-03-01 11:29:29 -08001183 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001184
1185 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001186 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001187
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001188 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001189 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1190 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001191}
1192
minyuececec102017-03-27 13:04:25 -07001193// Test that max_bitrate_bps in send stream config gets updated correctly when
1194// SetRtpSendParameters is called.
1195TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1196 webrtc::test::ScopedFieldTrials override_field_trials(
1197 "WebRTC-Audio-SendSideBwe/Enabled/");
1198 EXPECT_TRUE(SetupSendStream());
1199 cricket::AudioSendParameters send_parameters;
1200 send_parameters.codecs.push_back(kOpusCodec);
1201 SetSendParameters(send_parameters);
1202
1203 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1204 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1205 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1206
1207 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001208 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001209 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001210
1211 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1212 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1213}
1214
Seth Hampson24722b32017-12-22 09:36:42 -08001215// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1216// a value <= 0, setting the parameters returns false.
1217TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1218 EXPECT_TRUE(SetupSendStream());
1219 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1220 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1221 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1222 rtp_parameters.encodings[0].bitrate_priority);
1223
1224 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001225 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001226 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001227 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001228}
1229
1230// Test that the bitrate_priority in the send stream config gets updated when
1231// SetRtpSendParameters is set for the VoiceMediaChannel.
1232TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1233 EXPECT_TRUE(SetupSendStream());
1234 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1235
1236 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1237 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1238 rtp_parameters.encodings[0].bitrate_priority);
1239 double new_bitrate_priority = 2.0;
1240 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001241 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001242
1243 // The priority should get set for both the audio channel's rtp parameters
1244 // and the audio send stream's audio config.
1245 EXPECT_EQ(
1246 new_bitrate_priority,
1247 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1248 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1249}
1250
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001251// Test that GetRtpReceiveParameters returns the currently configured codecs.
1252TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1253 EXPECT_TRUE(SetupRecvStream());
1254 cricket::AudioRecvParameters parameters;
1255 parameters.codecs.push_back(kIsacCodec);
1256 parameters.codecs.push_back(kPcmuCodec);
1257 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1258
1259 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001260 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001261 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1262 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1263 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1264}
1265
deadbeefcb443432016-12-12 11:12:36 -08001266// Test that GetRtpReceiveParameters returns an SSRC.
1267TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1268 EXPECT_TRUE(SetupRecvStream());
1269 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001270 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001271 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001272 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001273}
1274
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001275// Test that if we set/get parameters multiple times, we get the same results.
1276TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1277 EXPECT_TRUE(SetupRecvStream());
1278 cricket::AudioRecvParameters parameters;
1279 parameters.codecs.push_back(kIsacCodec);
1280 parameters.codecs.push_back(kPcmuCodec);
1281 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1282
1283 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001284 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001285
1286 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001287 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001288
1289 // ... And this shouldn't change the params returned by
1290 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001291 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1292 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001293}
1294
deadbeef3bc15102017-04-20 19:25:07 -07001295// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1296// aren't signaled. It should return an empty "RtpEncodingParameters" when
1297// configured to receive an unsignaled stream and no packets have been received
1298// yet, and start returning the SSRC once a packet has been received.
1299TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1300 ASSERT_TRUE(SetupChannel());
1301 // Call necessary methods to configure receiving a default stream as
1302 // soon as it arrives.
1303 cricket::AudioRecvParameters parameters;
1304 parameters.codecs.push_back(kIsacCodec);
1305 parameters.codecs.push_back(kPcmuCodec);
1306 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1307
1308 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1309 // stream. Should return nothing.
1310 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1311
1312 // Set a sink for an unsignaled stream.
1313 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1314 // Value of "0" means "unsignaled stream".
1315 channel_->SetRawAudioSink(0, std::move(fake_sink));
1316
1317 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1318 // in this method means "unsignaled stream".
1319 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1320 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1321 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1322
1323 // Receive PCMU packet (SSRC=1).
1324 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1325
1326 // The |ssrc| member should still be unset.
1327 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1328 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1329 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1330}
1331
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332// Test that we apply codecs properly.
1333TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001334 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001335 cricket::AudioSendParameters parameters;
1336 parameters.codecs.push_back(kIsacCodec);
1337 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001338 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001340 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001341 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001342 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1343 EXPECT_EQ(96, send_codec_spec.payload_type);
1344 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1345 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1346 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001347 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001348 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001349}
1350
ossu20a4b3f2017-04-27 02:08:52 -07001351// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1352// AudioSendStream.
1353TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001354 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 cricket::AudioSendParameters parameters;
1356 parameters.codecs.push_back(kIsacCodec);
1357 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001358 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 parameters.codecs[0].id = 96;
1360 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001361 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001362 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001363 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001364 // Calling SetSendCodec again with same codec which is already set.
1365 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001366 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001367 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001368}
1369
ossu20a4b3f2017-04-27 02:08:52 -07001370// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1371// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001372
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001373// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001375 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001376 cricket::AudioSendParameters parameters;
1377 parameters.codecs.push_back(kOpusCodec);
1378 parameters.codecs[0].bitrate = 0;
1379 parameters.codecs[0].clockrate = 50000;
1380 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381}
1382
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001383// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001385 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001386 cricket::AudioSendParameters parameters;
1387 parameters.codecs.push_back(kOpusCodec);
1388 parameters.codecs[0].bitrate = 0;
1389 parameters.codecs[0].channels = 0;
1390 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391}
1392
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001393// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001394TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001395 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001396 cricket::AudioSendParameters parameters;
1397 parameters.codecs.push_back(kOpusCodec);
1398 parameters.codecs[0].bitrate = 0;
1399 parameters.codecs[0].channels = 0;
1400 parameters.codecs[0].params["stereo"] = "1";
1401 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402}
1403
1404// Test that if channel is 1 for opus and there's no stereo, we fail.
1405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kOpusCodec);
1409 parameters.codecs[0].bitrate = 0;
1410 parameters.codecs[0].channels = 1;
1411 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412}
1413
1414// Test that if channel is 1 for opus and stereo=0, we fail.
1415TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001416 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 cricket::AudioSendParameters parameters;
1418 parameters.codecs.push_back(kOpusCodec);
1419 parameters.codecs[0].bitrate = 0;
1420 parameters.codecs[0].channels = 1;
1421 parameters.codecs[0].params["stereo"] = "0";
1422 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423}
1424
1425// Test that if channel is 1 for opus and stereo=1, we fail.
1426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 0;
1431 parameters.codecs[0].channels = 1;
1432 parameters.codecs[0].params["stereo"] = "1";
1433 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434}
1435
ossu20a4b3f2017-04-27 02:08:52 -07001436// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001443 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444}
1445
ossu20a4b3f2017-04-27 02:08:52 -07001446// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001448 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 cricket::AudioSendParameters parameters;
1450 parameters.codecs.push_back(kOpusCodec);
1451 parameters.codecs[0].bitrate = 0;
1452 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001453 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001454 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455}
1456
ossu20a4b3f2017-04-27 02:08:52 -07001457// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001458TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001459 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001460 cricket::AudioSendParameters parameters;
1461 parameters.codecs.push_back(kOpusCodec);
1462 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001463 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001464 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001465 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001466 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001467
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001469 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001470 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001471}
1472
ossu20a4b3f2017-04-27 02:08:52 -07001473// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].bitrate = 0;
1479 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001480 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001481 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482}
1483
ossu20a4b3f2017-04-27 02:08:52 -07001484// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001490 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001491 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001492 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001493 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001494
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001497 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001498}
1499
ossu20a4b3f2017-04-27 02:08:52 -07001500// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001502 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 cricket::AudioSendParameters parameters;
1504 parameters.codecs.push_back(kOpusCodec);
1505 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001506 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001507 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1508 EXPECT_EQ(111, spec.payload_type);
1509 EXPECT_EQ(96000, spec.target_bitrate_bps);
1510 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001511 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001512 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513}
1514
ossu20a4b3f2017-04-27 02:08:52 -07001515// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001517 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].bitrate = 30000;
1521 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001523 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001532 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001533 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001534}
1535
ossu20a4b3f2017-04-27 02:08:52 -07001536// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001537TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001538 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001539 cricket::AudioSendParameters parameters;
1540 parameters.codecs.push_back(kOpusCodec);
1541 parameters.codecs[0].bitrate = 30000;
1542 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001544 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001545}
1546
stefan13f1a0a2016-11-30 07:22:58 -08001547TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1548 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1549 200000);
1550}
1551
1552TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1553 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1554}
1555
1556TEST_F(WebRtcVoiceEngineTestFake,
1557 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1558 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1559}
1560
1561TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1562 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1563}
1564
1565TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001566 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001567 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1568 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001569 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001570 // Setting max bitrate should keep previous min bitrate
1571 // Setting max bitrate should not reset start bitrate.
1572 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1573 SetSdpBitrateParameters(
1574 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1575 Field(&BitrateConstraints::start_bitrate_bps, -1),
1576 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001577 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001578}
1579
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001580// Test that we can enable NACK with opus as caller.
1581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].AddFeedbackParam(
1586 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1587 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591}
1592
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001593// Test that we can enable NACK with opus as callee.
1594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001595 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 cricket::AudioSendParameters parameters;
1597 parameters.codecs.push_back(kOpusCodec);
1598 parameters.codecs[0].AddFeedbackParam(
1599 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1600 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001603 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001605
1606 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001607 cricket::StreamParams::CreateLegacy(kSsrcX)));
1608 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001609}
1610
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611// Test that we can enable NACK on receive streams.
1612TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001613 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001614 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001615 cricket::AudioSendParameters parameters;
1616 parameters.codecs.push_back(kOpusCodec);
1617 parameters.codecs[0].AddFeedbackParam(
1618 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1619 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001620 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1621 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1624 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001625}
1626
1627// Test that we can disable NACK.
1628TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001629 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001630 cricket::AudioSendParameters parameters;
1631 parameters.codecs.push_back(kOpusCodec);
1632 parameters.codecs[0].AddFeedbackParam(
1633 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1634 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001638 parameters.codecs.clear();
1639 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001640 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001641 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642}
1643
1644// Test that we can disable NACK on receive streams.
1645TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001646 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001648 cricket::AudioSendParameters parameters;
1649 parameters.codecs.push_back(kOpusCodec);
1650 parameters.codecs[0].AddFeedbackParam(
1651 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1652 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1655 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001657 parameters.codecs.clear();
1658 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1661 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662}
1663
1664// Test that NACK is enabled on a new receive stream.
1665TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001666 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 cricket::AudioSendParameters parameters;
1668 parameters.codecs.push_back(kIsacCodec);
1669 parameters.codecs.push_back(kCn16000Codec);
1670 parameters.codecs[0].AddFeedbackParam(
1671 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1672 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001674 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_TRUE(AddRecvStream(kSsrcY));
1677 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1678 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1679 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680}
1681
stefanba4c0e42016-02-04 04:12:24 -08001682TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001683 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001684 cricket::AudioSendParameters send_parameters;
1685 send_parameters.codecs.push_back(kOpusCodec);
1686 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001688
1689 cricket::AudioRecvParameters recv_parameters;
1690 recv_parameters.codecs.push_back(kIsacCodec);
1691 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001692 EXPECT_TRUE(AddRecvStream(kSsrcX));
1693 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001694 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001695 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001696
ossudedfd282016-06-14 07:12:39 -07001697 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001700 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001701 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001702}
1703
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001704// Test that we can switch back and forth between Opus and ISAC with CN.
1705TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001706 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001707
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 cricket::AudioSendParameters opus_parameters;
1709 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001711 {
ossu20a4b3f2017-04-27 02:08:52 -07001712 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1713 EXPECT_EQ(111, spec.payload_type);
1714 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001715 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 cricket::AudioSendParameters isac_parameters;
1718 isac_parameters.codecs.push_back(kIsacCodec);
1719 isac_parameters.codecs.push_back(kCn16000Codec);
1720 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001721 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001722 {
ossu20a4b3f2017-04-27 02:08:52 -07001723 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1724 EXPECT_EQ(103, spec.payload_type);
1725 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001726 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001729 {
ossu20a4b3f2017-04-27 02:08:52 -07001730 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1731 EXPECT_EQ(111, spec.payload_type);
1732 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734}
1735
1736// Test that we handle various ways of specifying bitrate.
1737TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001738 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters parameters;
1740 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001741 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001742 {
ossu20a4b3f2017-04-27 02:08:52 -07001743 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1744 EXPECT_EQ(103, spec.payload_type);
1745 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1746 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001747 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001748
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001751 {
ossu20a4b3f2017-04-27 02:08:52 -07001752 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1753 EXPECT_EQ(103, spec.payload_type);
1754 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1755 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001756 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001758 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001759 {
ossu20a4b3f2017-04-27 02:08:52 -07001760 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1761 EXPECT_EQ(103, spec.payload_type);
1762 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1763 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001764 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001768 {
ossu20a4b3f2017-04-27 02:08:52 -07001769 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1770 EXPECT_EQ(0, spec.payload_type);
1771 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1772 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001773 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001776 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001777 {
ossu20a4b3f2017-04-27 02:08:52 -07001778 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1779 EXPECT_EQ(0, spec.payload_type);
1780 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1781 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001782 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001783
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 parameters.codecs[0] = kOpusCodec;
1785 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001787 {
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(111, spec.payload_type);
1790 EXPECT_STREQ("opus", spec.format.name.c_str());
1791 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001792 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793}
1794
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001795// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001797 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001798 cricket::AudioSendParameters parameters;
1799 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001800}
1801
1802// Test that we can set send codecs even with telephone-event codec as the first
1803// one on the list.
1804TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001805 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001806 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001807 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001808 parameters.codecs.push_back(kIsacCodec);
1809 parameters.codecs.push_back(kPcmuCodec);
1810 parameters.codecs[0].id = 98; // DTMF
1811 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001812 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001813 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1814 EXPECT_EQ(96, spec.payload_type);
1815 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001816 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001817 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001818}
1819
Harald Alvestranda1f66612018-02-21 11:24:23 +01001820// Test that CanInsertDtmf() is governed by the send flag
1821TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1822 EXPECT_TRUE(SetupSendStream());
1823 cricket::AudioSendParameters parameters;
1824 parameters.codecs.push_back(kTelephoneEventCodec1);
1825 parameters.codecs.push_back(kPcmuCodec);
1826 parameters.codecs[0].id = 98; // DTMF
1827 parameters.codecs[1].id = 96;
1828 SetSendParameters(parameters);
1829 EXPECT_FALSE(channel_->CanInsertDtmf());
1830 SetSend(true);
1831 EXPECT_TRUE(channel_->CanInsertDtmf());
1832 SetSend(false);
1833 EXPECT_FALSE(channel_->CanInsertDtmf());
1834}
1835
solenberg31642aa2016-03-14 08:00:37 -07001836// Test that payload type range is limited for telephone-event codec.
1837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001839 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001840 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001841 parameters.codecs.push_back(kIsacCodec);
1842 parameters.codecs[0].id = 0; // DTMF
1843 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001845 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001846 EXPECT_TRUE(channel_->CanInsertDtmf());
1847 parameters.codecs[0].id = 128; // DTMF
1848 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1849 EXPECT_FALSE(channel_->CanInsertDtmf());
1850 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001852 EXPECT_TRUE(channel_->CanInsertDtmf());
1853 parameters.codecs[0].id = -1; // DTMF
1854 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1855 EXPECT_FALSE(channel_->CanInsertDtmf());
1856}
1857
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001858// Test that we can set send codecs even with CN codec as the first
1859// one on the list.
1860TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001861 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001862 cricket::AudioSendParameters parameters;
1863 parameters.codecs.push_back(kCn16000Codec);
1864 parameters.codecs.push_back(kIsacCodec);
1865 parameters.codecs.push_back(kPcmuCodec);
1866 parameters.codecs[0].id = 98; // wideband CN
1867 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001868 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001869 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1870 EXPECT_EQ(96, send_codec_spec.payload_type);
1871 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001872 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001873}
1874
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001875// Test that we set VAD and DTMF types correctly as caller.
1876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001877 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001878 cricket::AudioSendParameters parameters;
1879 parameters.codecs.push_back(kIsacCodec);
1880 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001881 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 parameters.codecs.push_back(kCn16000Codec);
1883 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001884 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001885 parameters.codecs[0].id = 96;
1886 parameters.codecs[2].id = 97; // wideband CN
1887 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001888 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001889 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1890 EXPECT_EQ(96, send_codec_spec.payload_type);
1891 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001892 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001893 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001894 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001895 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896}
1897
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001898// Test that we set VAD and DTMF types correctly as callee.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kIsacCodec);
1903 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001904 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 parameters.codecs.push_back(kCn16000Codec);
1906 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001907 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 parameters.codecs[0].id = 96;
1909 parameters.codecs[2].id = 97; // wideband CN
1910 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001912 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001913 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001914
ossu20a4b3f2017-04-27 02:08:52 -07001915 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1916 EXPECT_EQ(96, send_codec_spec.payload_type);
1917 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001918 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001919 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001920 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001921 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001922}
1923
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001924// Test that we only apply VAD if we have a CN codec that matches the
1925// send codec clockrate.
1926TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001927 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 parameters.codecs.push_back(kIsacCodec);
1931 parameters.codecs.push_back(kCn16000Codec);
1932 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001933 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001934 {
ossu20a4b3f2017-04-27 02:08:52 -07001935 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1936 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001937 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001938 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001939 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001940 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001943 {
ossu20a4b3f2017-04-27 02:08:52 -07001944 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1945 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001946 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001947 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001951 {
ossu20a4b3f2017-04-27 02:08:52 -07001952 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1953 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001954 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001955 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001956 }
Brave Yao5225dd82015-03-26 07:39:19 +08001957 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001960 {
ossu20a4b3f2017-04-27 02:08:52 -07001961 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1962 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001963 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001964 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965}
1966
1967// Test that we perform case-insensitive matching of codec names.
1968TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001969 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001970 cricket::AudioSendParameters parameters;
1971 parameters.codecs.push_back(kIsacCodec);
1972 parameters.codecs.push_back(kPcmuCodec);
1973 parameters.codecs.push_back(kCn16000Codec);
1974 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001975 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001976 parameters.codecs[0].name = "iSaC";
1977 parameters.codecs[0].id = 96;
1978 parameters.codecs[2].id = 97; // wideband CN
1979 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001980 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001981 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1982 EXPECT_EQ(96, send_codec_spec.payload_type);
1983 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001984 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001985 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001986 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001987 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988}
1989
stefanba4c0e42016-02-04 04:12:24 -08001990class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1991 public:
1992 WebRtcVoiceEngineWithSendSideBweTest()
1993 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1994};
1995
1996TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1997 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001998 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001999 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002000 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2001 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2002 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002003 extension.id);
2004 return;
2005 }
2006 }
2007 FAIL() << "Transport sequence number extension not in header-extension list.";
2008}
2009
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002010// Test support for audio level header extension.
2011TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002012 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002013}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002014TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002015 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002016}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002017
solenbergd4adce42016-11-17 06:26:52 -08002018// Test support for transport sequence number header extension.
2019TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2020 TestSetSendRtpHeaderExtensions(
2021 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002022}
solenbergd4adce42016-11-17 06:26:52 -08002023TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2024 TestSetRecvRtpHeaderExtensions(
2025 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002026}
2027
solenberg1ac56142015-10-13 03:58:19 -07002028// Test that we can create a channel and start sending on it.
2029TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002030 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002031 SetSendParameters(send_parameters_);
2032 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002033 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002034 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002035 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002036}
2037
2038// Test that a channel will send if and only if it has a source and is enabled
2039// for sending.
2040TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002041 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002042 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002043 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002044 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002045 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2046 SetAudioSend(kSsrcX, true, &fake_source_);
2047 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2048 SetAudioSend(kSsrcX, true, nullptr);
2049 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002050}
2051
solenberg94218532016-06-16 10:53:22 -07002052// Test that a channel is muted/unmuted.
2053TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2054 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002055 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002056 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2057 SetAudioSend(kSsrcX, true, nullptr);
2058 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2059 SetAudioSend(kSsrcX, false, nullptr);
2060 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002061}
2062
solenberg6d6e7c52016-04-13 09:07:30 -07002063// Test that SetSendParameters() does not alter a stream's send state.
2064TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2065 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002066 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002067
2068 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002069 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002070 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002071
2072 // Changing RTP header extensions will recreate the AudioSendStream.
2073 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002074 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002076 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002077
2078 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002079 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002080 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002081
2082 // Changing RTP header extensions will recreate the AudioSendStream.
2083 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002084 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002086}
2087
solenberg1ac56142015-10-13 03:58:19 -07002088// Test that we can create a channel and start playing out on it.
2089TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002090 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002091 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002092 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002093 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002094 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002095 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002096}
2097
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002098// Test that we can add and remove send streams.
2099TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2100 SetupForMultiSendStream();
2101
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002103 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002104
solenbergc96df772015-10-21 13:01:53 -07002105 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002107 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002108 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002110 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002111 }
tfarina5237aaf2015-11-10 23:44:30 -08002112 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113
solenbergc96df772015-10-21 13:01:53 -07002114 // Delete the send streams.
2115 for (uint32_t ssrc : kSsrcs4) {
2116 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002117 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002118 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002119 }
solenbergc96df772015-10-21 13:01:53 -07002120 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002121}
2122
2123// Test SetSendCodecs correctly configure the codecs in all send streams.
2124TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2125 SetupForMultiSendStream();
2126
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002128 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002130 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131 }
2132
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002133 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002135 parameters.codecs.push_back(kIsacCodec);
2136 parameters.codecs.push_back(kCn16000Codec);
2137 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002138 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139
2140 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002141 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002142 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2143 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002144 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2145 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002146 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002147 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148 }
2149
minyue7a973442016-10-20 03:27:12 -07002150 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002151 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002152 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002153 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002154 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2155 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002156 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2157 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002158 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002159 }
2160}
2161
2162// Test we can SetSend on all send streams correctly.
2163TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2164 SetupForMultiSendStream();
2165
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002166 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002167 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002169 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002170 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002171 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002172 }
2173
2174 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002175 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002176 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002178 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 }
2180
2181 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002182 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002183 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002184 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002185 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002186 }
2187}
2188
2189// Test we can set the correct statistics on all send streams.
2190TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2191 SetupForMultiSendStream();
2192
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002194 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002196 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197 }
solenberg85a04962015-10-27 03:35:21 -07002198
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002199 // Create a receive stream to check that none of the send streams end up in
2200 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002202
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002203 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002204 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002205 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002206 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207
solenberg85a04962015-10-27 03:35:21 -07002208 // Check stats for the added streams.
2209 {
2210 cricket::VoiceMediaInfo info;
2211 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002212
solenberg85a04962015-10-27 03:35:21 -07002213 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002214 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002215 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002216 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002217 }
hbos1acfbd22016-11-17 23:43:29 -08002218 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002219
2220 // We have added one receive stream. We should see empty stats.
2221 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002222 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002223 }
solenberg1ac56142015-10-13 03:58:19 -07002224
solenberg2100c0b2017-03-01 11:29:29 -08002225 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002226 {
2227 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002228 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002229 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002230 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002231 EXPECT_EQ(0u, info.receivers.size());
2232 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002233
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002234 // Deliver a new packet - a default receive stream should be created and we
2235 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002236 {
2237 cricket::VoiceMediaInfo info;
2238 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2239 SetAudioReceiveStreamStats();
2240 EXPECT_EQ(true, channel_->GetStats(&info));
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 EXPECT_EQ(1u, info.receivers.size());
2243 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002244 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002245 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002246}
2247
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002248// Test that we can add and remove receive streams, and do proper send/playout.
2249// We can receive on multiple streams while sending one stream.
2250TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002251 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002252
solenberg1ac56142015-10-13 03:58:19 -07002253 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002254 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002255 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002256
solenberg1ac56142015-10-13 03:58:19 -07002257 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002258 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002259 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002260 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002261
solenberg1ac56142015-10-13 03:58:19 -07002262 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002263 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002264
2265 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002266 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2267 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2268 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002269
2270 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002271 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002272 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002273
2274 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002275 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002276 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2277 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002278
aleloi84ef6152016-08-04 05:28:21 -07002279 // Restart playout and make sure recv streams are played out.
2280 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002281 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2282 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002283
aleloi84ef6152016-08-04 05:28:21 -07002284 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2286 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287}
2288
wu@webrtc.org97077a32013-10-25 21:18:33 +00002289TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002290 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002291 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2292 .Times(1)
2293 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002294 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2295 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002296 send_parameters_.options.tx_agc_target_dbov = 3;
2297 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2298 send_parameters_.options.tx_agc_limiter = true;
2299 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002300 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2301 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2302 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002303 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002304}
2305
minyue6b825df2016-10-31 04:08:32 -07002306TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2307 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002308 send_parameters_.options.audio_network_adaptor = true;
2309 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002310 SetSendParameters(send_parameters_);
2311 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002312 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002313}
2314
2315TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2316 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002317 send_parameters_.options.audio_network_adaptor = true;
2318 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002319 SetSendParameters(send_parameters_);
2320 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002321 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002322 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002323 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002324 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002325 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002326}
2327
2328TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2329 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002330 send_parameters_.options.audio_network_adaptor = true;
2331 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002332 SetSendParameters(send_parameters_);
2333 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002335 const int initial_num = call_.GetNumCreatedSendStreams();
2336 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002337 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002338 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2339 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002340 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002341 // AudioSendStream not expected to be recreated.
2342 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2343 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002344 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002345}
2346
michaelt6672b262017-01-11 10:17:59 -08002347class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2348 : public WebRtcVoiceEngineTestFake {
2349 public:
2350 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2351 : WebRtcVoiceEngineTestFake(
2352 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2353 "Enabled/") {}
2354};
2355
2356TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2357 EXPECT_TRUE(SetupSendStream());
2358 cricket::AudioSendParameters parameters;
2359 parameters.codecs.push_back(kOpusCodec);
2360 SetSendParameters(parameters);
2361 const int initial_num = call_.GetNumCreatedSendStreams();
2362 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2363
2364 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2365 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002366 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2367 constexpr int kMinOverheadBps =
2368 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002369
2370 constexpr int kOpusMinBitrateBps = 6000;
2371 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002372 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002373 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002374 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002375 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002376
Oskar Sundbom78807582017-11-16 11:09:55 +01002377 parameters.options.audio_network_adaptor = true;
2378 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002379 SetSendParameters(parameters);
2380
ossu11bfc532017-02-16 05:37:06 -08002381 constexpr int kMinOverheadWithAnaBps =
2382 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002383
2384 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002385 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002386
minyuececec102017-03-27 13:04:25 -07002387 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002388 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002389}
2390
minyuececec102017-03-27 13:04:25 -07002391// This test is similar to
2392// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2393// additional field trial.
2394TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2395 SetRtpSendParameterUpdatesMaxBitrate) {
2396 EXPECT_TRUE(SetupSendStream());
2397 cricket::AudioSendParameters send_parameters;
2398 send_parameters.codecs.push_back(kOpusCodec);
2399 SetSendParameters(send_parameters);
2400
2401 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2402 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2403 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2404
2405 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002406 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002407 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002408
2409 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2410#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2411 constexpr int kMinOverhead = 3333;
2412#else
2413 constexpr int kMinOverhead = 6666;
2414#endif
2415 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2416}
2417
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002419// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002421 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002422 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423}
2424
2425TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2426 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002427 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002428 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002429 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002430 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002431 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002432 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002433 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434
solenberg85a04962015-10-27 03:35:21 -07002435 // Check stats for the added streams.
2436 {
2437 cricket::VoiceMediaInfo info;
2438 EXPECT_EQ(true, channel_->GetStats(&info));
2439
2440 // We have added one send stream. We should see the stats we've set.
2441 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002442 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002443 // We have added one receive stream. We should see empty stats.
2444 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002445 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002446 }
solenberg1ac56142015-10-13 03:58:19 -07002447
solenberg566ef242015-11-06 15:34:49 -08002448 // Start sending - this affects some reported stats.
2449 {
2450 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002451 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002452 EXPECT_EQ(true, channel_->GetStats(&info));
2453 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002454 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002455 }
2456
solenberg2100c0b2017-03-01 11:29:29 -08002457 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002458 {
2459 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002460 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002461 EXPECT_EQ(true, channel_->GetStats(&info));
2462 EXPECT_EQ(1u, info.senders.size());
2463 EXPECT_EQ(0u, info.receivers.size());
2464 }
solenberg1ac56142015-10-13 03:58:19 -07002465
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002466 // Deliver a new packet - a default receive stream should be created and we
2467 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002468 {
2469 cricket::VoiceMediaInfo info;
2470 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2471 SetAudioReceiveStreamStats();
2472 EXPECT_EQ(true, channel_->GetStats(&info));
2473 EXPECT_EQ(1u, info.senders.size());
2474 EXPECT_EQ(1u, info.receivers.size());
2475 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002476 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002477 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002478}
2479
2480// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002481// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002483 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002484 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2485 EXPECT_TRUE(AddRecvStream(kSsrcY));
2486 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487}
2488
2489// Test that the local SSRC is the same on sending and receiving channels if the
2490// receive channel is created before the send channel.
2491TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002492 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002493 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002495 cricket::StreamParams::CreateLegacy(kSsrcX)));
2496 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2497 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498}
2499
2500// Test that we can properly receive packets.
2501TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002502 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002503 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002505
2506 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2507 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508}
2509
2510// Test that we can properly receive packets on multiple streams.
2511TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002512 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002513 const uint32_t ssrc1 = 1;
2514 const uint32_t ssrc2 = 2;
2515 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002516 EXPECT_TRUE(AddRecvStream(ssrc1));
2517 EXPECT_TRUE(AddRecvStream(ssrc2));
2518 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002520 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002521 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002523 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 }
mflodman3d7db262016-04-29 00:57:13 -07002525
2526 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2527 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2528 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2529
2530 EXPECT_EQ(s1.received_packets(), 0);
2531 EXPECT_EQ(s2.received_packets(), 0);
2532 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002533
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_EQ(s1.received_packets(), 0);
2536 EXPECT_EQ(s2.received_packets(), 0);
2537 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002538
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002539 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002540 EXPECT_EQ(s1.received_packets(), 1);
2541 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2542 EXPECT_EQ(s2.received_packets(), 0);
2543 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002544
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002545 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002546 EXPECT_EQ(s1.received_packets(), 1);
2547 EXPECT_EQ(s2.received_packets(), 1);
2548 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2549 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002550
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002551 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002552 EXPECT_EQ(s1.received_packets(), 1);
2553 EXPECT_EQ(s2.received_packets(), 1);
2554 EXPECT_EQ(s3.received_packets(), 1);
2555 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002556
mflodman3d7db262016-04-29 00:57:13 -07002557 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2558 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2559 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560}
2561
solenberg2100c0b2017-03-01 11:29:29 -08002562// Test that receiving on an unsignaled stream works (a stream is created).
2563TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002564 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002565 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002566
solenberg7e63ef02015-11-20 00:19:43 -08002567 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002568
Mirko Bonadeif859e552018-05-30 15:31:29 +02002569 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002570 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2571 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002572}
2573
Seth Hampson5897a6e2018-04-03 11:16:33 -07002574// Tests that when we add a stream without SSRCs, but contains a stream_id
2575// that it is stored and its stream id is later used when the first packet
2576// arrives to properly create a receive stream with a sync label.
2577TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2578 const char kSyncLabel[] = "sync_label";
2579 EXPECT_TRUE(SetupChannel());
2580 cricket::StreamParams unsignaled_stream;
2581 unsignaled_stream.set_stream_ids({kSyncLabel});
2582 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2583 // The stream shouldn't have been created at this point because it doesn't
2584 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002585 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002586
2587 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2588
Mirko Bonadeif859e552018-05-30 15:31:29 +02002589 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002590 EXPECT_TRUE(
2591 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2592 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2593
2594 // Removing the unsignaled stream clears the cached parameters. If a new
2595 // default unsignaled receive stream is created it will not have a sync group.
2596 channel_->RemoveRecvStream(0);
2597 channel_->RemoveRecvStream(kSsrc1);
2598
2599 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2600
Mirko Bonadeif859e552018-05-30 15:31:29 +02002601 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002602 EXPECT_TRUE(
2603 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2604 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2605}
2606
solenberg2100c0b2017-03-01 11:29:29 -08002607// Test that receiving N unsignaled stream works (streams will be created), and
2608// that packets are forwarded to them all.
2609TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002610 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002611 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002612 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2613
solenberg2100c0b2017-03-01 11:29:29 -08002614 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002615 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002616 rtc::SetBE32(&packet[8], ssrc);
2617 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002618
solenberg2100c0b2017-03-01 11:29:29 -08002619 // Verify we have one new stream for each loop iteration.
2620 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002621 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2622 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002623 }
mflodman3d7db262016-04-29 00:57:13 -07002624
solenberg2100c0b2017-03-01 11:29:29 -08002625 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002626 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002627 rtc::SetBE32(&packet[8], ssrc);
2628 DeliverPacket(packet, sizeof(packet));
2629
solenbergebb349d2017-03-13 05:46:15 -07002630 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002631 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2632 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2633 }
2634
2635 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2636 constexpr uint32_t kAnotherSsrc = 667;
2637 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002638 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002639
2640 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002641 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002642 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002643 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002644 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2645 EXPECT_EQ(2, streams[i]->received_packets());
2646 }
2647 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2648 EXPECT_EQ(1, streams[i]->received_packets());
2649 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002650 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002651}
2652
solenberg2100c0b2017-03-01 11:29:29 -08002653// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002654// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002655TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002657 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002658 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2659
2660 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002661 const uint32_t signaled_ssrc = 1;
2662 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002663 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002664 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002665 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2666 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002667 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002668
2669 // Note that the first unknown SSRC cannot be 0, because we only support
2670 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002671 const uint32_t unsignaled_ssrc = 7011;
2672 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002673 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002674 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2675 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002676 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002677
2678 DeliverPacket(packet, sizeof(packet));
2679 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2680
2681 rtc::SetBE32(&packet[8], signaled_ssrc);
2682 DeliverPacket(packet, sizeof(packet));
2683 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002684 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002685}
2686
solenberg4904fb62017-02-17 12:01:14 -08002687// Two tests to verify that adding a receive stream with the same SSRC as a
2688// previously added unsignaled stream will only recreate underlying stream
2689// objects if the stream parameters have changed.
2690TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2691 EXPECT_TRUE(SetupChannel());
2692
2693 // Spawn unsignaled stream with SSRC=1.
2694 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002695 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002696 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2697 sizeof(kPcmuFrame)));
2698
2699 // Verify that the underlying stream object in Call is not recreated when a
2700 // stream with SSRC=1 is added.
2701 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002702 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002703 int audio_receive_stream_id = streams.front()->id();
2704 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002705 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002706 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2707}
2708
2709TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2710 EXPECT_TRUE(SetupChannel());
2711
2712 // Spawn unsignaled stream with SSRC=1.
2713 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002714 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002715 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2716 sizeof(kPcmuFrame)));
2717
2718 // Verify that the underlying stream object in Call *is* recreated when a
2719 // stream with SSRC=1 is added, and which has changed stream parameters.
2720 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002721 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002722 int audio_receive_stream_id = streams.front()->id();
2723 cricket::StreamParams stream_params;
2724 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002725 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002726 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002727 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002728 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2729}
2730
solenberg1ac56142015-10-13 03:58:19 -07002731// Test that AddRecvStream creates new stream.
2732TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002733 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002734 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735}
2736
2737// Test that after adding a recv stream, we do not decode more codecs than
2738// those previously passed into SetRecvCodecs.
2739TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002740 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002741 cricket::AudioRecvParameters parameters;
2742 parameters.codecs.push_back(kIsacCodec);
2743 parameters.codecs.push_back(kPcmuCodec);
2744 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002745 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002746 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2747 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2748 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749}
2750
2751// Test that we properly clean up any streams that were added, even if
2752// not explicitly removed.
2753TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002754 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002755 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002756 EXPECT_TRUE(AddRecvStream(1));
2757 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002758
Mirko Bonadeif859e552018-05-30 15:31:29 +02002759 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2760 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761 delete channel_;
2762 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002763 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2764 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765}
2766
wu@webrtc.org78187522013-10-07 23:32:02 +00002767TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002768 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002769 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002770}
2771
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002772TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002773 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002774 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002775 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002776}
2777
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002778// Test the InsertDtmf on default send stream as caller.
2779TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002780 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781}
2782
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002783// Test the InsertDtmf on default send stream as callee
2784TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002785 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002786}
2787
2788// Test the InsertDtmf on specified send stream as caller.
2789TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002790 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002791}
2792
2793// Test the InsertDtmf on specified send stream as callee.
2794TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002795 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796}
2797
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002798TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002799 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002800 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002801 EXPECT_CALL(adm_,
2802 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2803 EXPECT_CALL(adm_,
2804 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2805 EXPECT_CALL(adm_,
2806 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002807
Mirko Bonadeif859e552018-05-30 15:31:29 +02002808 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002809 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002810
solenberg246b8172015-12-08 09:50:23 -08002811 // Nothing set in AudioOptions, so everything should be as default.
2812 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002813 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002814 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002815 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002816 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817
2818 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002819 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2820 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002821 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002822 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823
2824 // Turn echo cancellation back on, with settings, and make sure
2825 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002826 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002828 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002829 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002831 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2832 // control.
solenberg76377c52017-02-21 00:54:31 -08002833 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002835 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002836 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002837
2838 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002839 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2840 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002841 send_parameters_.options.delay_agnostic_aec = false;
2842 send_parameters_.options.extended_filter_aec = false;
2843 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002844 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002845
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002846 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002847 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2848 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002849 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002850 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002851
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002853 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2854 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002855 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002856 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002857 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002858 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859
2860 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002861 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002863 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002864 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002866 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002868 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002869 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002871 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002873 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002876 send_parameters_.options.noise_suppression = false;
2877 send_parameters_.options.highpass_filter = false;
2878 send_parameters_.options.typing_detection = false;
2879 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002880 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002881 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
solenberg1ac56142015-10-13 03:58:19 -07002883 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002884 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
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));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002888 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002889 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002891 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892}
2893
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002894TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002895 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002896 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002897 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002898 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002899 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002900 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002901 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002902 EXPECT_CALL(adm_,
2903 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2904 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2905 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002906 webrtc::AudioProcessing::Config apm_config;
2907 EXPECT_CALL(*apm_, GetConfig())
2908 .Times(10)
2909 .WillRepeatedly(ReturnPointee(&apm_config));
2910 EXPECT_CALL(*apm_, ApplyConfig(_))
2911 .Times(10)
2912 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002913 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002914
kwiberg686a8ef2016-02-26 03:00:35 -08002915 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002916 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002917 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002918 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002919 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002920 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921
2922 // Have to add a stream to make SetSend work.
2923 cricket::StreamParams stream1;
2924 stream1.ssrcs.push_back(1);
2925 channel1->AddSendStream(stream1);
2926 cricket::StreamParams stream2;
2927 stream2.ssrcs.push_back(2);
2928 channel2->AddSendStream(stream2);
2929
2930 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002931 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002932 parameters_options_all.options.echo_cancellation = true;
2933 parameters_options_all.options.auto_gain_control = true;
2934 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2936 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002937 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002938 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002941 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002942 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002943 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002944 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945
2946 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002947 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002948 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002949 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2950 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002951 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002952 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002953 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002954 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002955 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002956 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002957 expected_options.echo_cancellation = true;
2958 expected_options.auto_gain_control = true;
2959 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002960 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961
2962 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002963 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002964 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002965 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2966 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002967 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002968 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002969 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002970 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002971 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002972 expected_options.echo_cancellation = true;
2973 expected_options.auto_gain_control = false;
2974 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002975 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002976
solenberg76377c52017-02-21 00:54:31 -08002977 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2978 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002979 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002980 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002981 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002982 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002983 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984
solenberg76377c52017-02-21 00:54:31 -08002985 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2986 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002987 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002988 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002989 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002990 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002991 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992
solenberg76377c52017-02-21 00:54:31 -08002993 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2994 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002995 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002996 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002997 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002998 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002999 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003002 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3003 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003004 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3005 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08003006 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3007 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
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(false)).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 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01003013 expected_options.echo_cancellation = true;
3014 expected_options.auto_gain_control = false;
3015 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003016 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003017}
3018
wu@webrtc.orgde305012013-10-31 15:40:38 +00003019// This test verifies DSCP settings are properly applied on voice media channel.
3020TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003021 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003022 cricket::FakeNetworkInterface network_interface;
3023 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003024 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003025
peahb1c9d1d2017-07-25 15:45:24 -07003026 webrtc::AudioProcessing::Config apm_config;
3027 EXPECT_CALL(*apm_, GetConfig())
3028 .Times(3)
3029 .WillRepeatedly(ReturnPointee(&apm_config));
3030 EXPECT_CALL(*apm_, ApplyConfig(_))
3031 .Times(3)
3032 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003033 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003034
solenbergbc37fc82016-04-04 09:54:44 -07003035 channel.reset(
3036 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003037 channel->SetInterface(&network_interface);
3038 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3039 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3040
3041 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003042 channel.reset(
3043 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003044 channel->SetInterface(&network_interface);
3045 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3046
3047 // Verify that setting the option to false resets the
3048 // DiffServCodePoint.
3049 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003050 channel.reset(
3051 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003052 channel->SetInterface(&network_interface);
3053 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3054 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3055
3056 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003057}
3058
solenberg4bac9c52015-10-09 02:32:53 -07003059TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003060 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003061 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003063 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003064 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003065 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3066 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3067 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003068}
3069
solenberg2100c0b2017-03-01 11:29:29 -08003070TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003071 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003072
3073 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003074 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003075 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3076
3077 // Should remember the volume "2" which will be set on new unsignaled streams,
3078 // and also set the gain to 2 on existing unsignaled streams.
3079 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3080 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3081
3082 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3083 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3084 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3085 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3086 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3087 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3088
3089 // Setting gain with SSRC=0 should affect all unsignaled streams.
3090 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003091 if (kMaxUnsignaledRecvStreams > 1) {
3092 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3093 }
solenberg2100c0b2017-03-01 11:29:29 -08003094 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3095
3096 // Setting gain on an individual stream affects only that.
3097 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003098 if (kMaxUnsignaledRecvStreams > 1) {
3099 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3100 }
solenberg2100c0b2017-03-01 11:29:29 -08003101 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003102}
3103
Seth Hampson845e8782018-03-02 11:34:10 -08003104TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003105 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003106 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003107
solenbergff976312016-03-30 23:28:51 -07003108 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003109 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003110 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003111 // Creating two channels to make sure that sync label is set properly for both
3112 // the default voice channel and following ones.
3113 EXPECT_TRUE(channel_->AddRecvStream(sp));
3114 sp.ssrcs[0] += 1;
3115 EXPECT_TRUE(channel_->AddRecvStream(sp));
3116
Mirko Bonadeif859e552018-05-30 15:31:29 +02003117 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003118 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003119 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003120 << "SyncGroup should be set based on stream id";
3121 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003122 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003123 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003124}
3125
solenberg3a941542015-11-16 07:34:50 -08003126// TODO(solenberg): Remove, once recv streams are configured through Call.
3127// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003128TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003129 // Test that setting the header extensions results in the expected state
3130 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003131 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003132 ssrcs.push_back(223);
3133 ssrcs.push_back(224);
3134
solenbergff976312016-03-30 23:28:51 -07003135 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003136 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003137 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003138 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 cricket::StreamParams::CreateLegacy(ssrc)));
3140 }
3141
Mirko Bonadeif859e552018-05-30 15:31:29 +02003142 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003143 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003144 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003145 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003146 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003147 }
3148
3149 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003150 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003151 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003152 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003153 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003154 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003155 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003156 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003157 EXPECT_NE(nullptr, s);
3158 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003159 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3160 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003161 for (const auto& s_ext : s_exts) {
3162 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003163 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003164 }
3165 }
3166 }
3167 }
3168
3169 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003170 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003171 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003172 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003173 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003174 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003175 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003176}
3177
3178TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3179 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003180 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003181 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003182 static const unsigned char kRtcp[] = {
3183 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3184 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3187 };
jbaucheec21bd2016-03-20 06:15:43 -07003188 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003189
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003191 cricket::WebRtcVoiceMediaChannel* media_channel =
3192 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003193 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003194 EXPECT_TRUE(media_channel->AddRecvStream(
3195 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3196
Mirko Bonadeif859e552018-05-30 15:31:29 +02003197 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003198 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003199 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 EXPECT_EQ(0, s->received_packets());
3201 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3202 EXPECT_EQ(1, s->received_packets());
3203 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3204 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003205}
Minyue2013aec2015-05-13 14:14:42 +02003206
solenberg0a617e22015-10-20 15:49:38 -07003207// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003208// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003209TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003210 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_TRUE(AddRecvStream(kSsrcY));
3212 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003213 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003214 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3215 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3216 EXPECT_TRUE(AddRecvStream(kSsrcW));
3217 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003218}
3219
solenberg7602aab2016-11-14 11:30:07 -08003220TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3221 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003222 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003223 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003224 cricket::StreamParams::CreateLegacy(kSsrcY)));
3225 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3226 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3227 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003228 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003229 cricket::StreamParams::CreateLegacy(kSsrcW)));
3230 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3231 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003232}
stefan658910c2015-09-03 05:48:32 -07003233
deadbeef884f5852016-01-15 09:20:04 -08003234TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003235 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003236 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3237 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003238
3239 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003240 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3241 EXPECT_TRUE(AddRecvStream(kSsrcX));
3242 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003243
3244 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003245 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3246 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003247
3248 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003249 channel_->SetRawAudioSink(kSsrcX, nullptr);
3250 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003251}
3252
solenberg2100c0b2017-03-01 11:29:29 -08003253TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003254 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003255 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3256 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003257 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3258 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003259
3260 // Should be able to set a default sink even when no stream exists.
3261 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3262
solenberg2100c0b2017-03-01 11:29:29 -08003263 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3264 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003265 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003267
3268 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003269 channel_->SetRawAudioSink(kSsrc0, nullptr);
3270 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003271
3272 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003273 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3274 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003275
3276 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003278 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3280
3281 // Spawn another unsignaled stream - it should be assigned the default sink
3282 // and the previous unsignaled stream should lose it.
3283 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3284 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3285 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3286 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003287 if (kMaxUnsignaledRecvStreams > 1) {
3288 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3289 }
solenberg2100c0b2017-03-01 11:29:29 -08003290 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3291
3292 // Reset the default sink - the second unsignaled stream should lose it.
3293 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003294 if (kMaxUnsignaledRecvStreams > 1) {
3295 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3296 }
solenberg2100c0b2017-03-01 11:29:29 -08003297 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3298
3299 // Try setting the default sink while two streams exists.
3300 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003301 if (kMaxUnsignaledRecvStreams > 1) {
3302 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3303 }
solenberg2100c0b2017-03-01 11:29:29 -08003304 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3305
3306 // Try setting the sink for the first unsignaled stream using its known SSRC.
3307 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003308 if (kMaxUnsignaledRecvStreams > 1) {
3309 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3310 }
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003312 if (kMaxUnsignaledRecvStreams > 1) {
3313 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3314 }
deadbeef884f5852016-01-15 09:20:04 -08003315}
3316
skvlad7a43d252016-03-22 15:32:27 -07003317// Test that, just like the video channel, the voice channel communicates the
3318// network state to the call.
3319TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003320 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003321
3322 EXPECT_EQ(webrtc::kNetworkUp,
3323 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3324 EXPECT_EQ(webrtc::kNetworkUp,
3325 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3326
3327 channel_->OnReadyToSend(false);
3328 EXPECT_EQ(webrtc::kNetworkDown,
3329 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3330 EXPECT_EQ(webrtc::kNetworkUp,
3331 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3332
3333 channel_->OnReadyToSend(true);
3334 EXPECT_EQ(webrtc::kNetworkUp,
3335 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3336 EXPECT_EQ(webrtc::kNetworkUp,
3337 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3338}
3339
aleloi18e0b672016-10-04 02:45:47 -07003340// Test that playout is still started after changing parameters
3341TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3342 SetupRecvStream();
3343 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003344 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003345
3346 // Changing RTP header extensions will recreate the AudioReceiveStream.
3347 cricket::AudioRecvParameters parameters;
3348 parameters.extensions.push_back(
3349 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3350 channel_->SetRecvParameters(parameters);
3351
solenberg2100c0b2017-03-01 11:29:29 -08003352 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003353}
3354
Zhi Huangfa266ef2017-12-13 10:27:46 -08003355// Tests when GetSources is called with non-existing ssrc, it will return an
3356// empty list of RtpSource without crashing.
3357TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3358 // Setup an recv stream with |kSsrcX|.
3359 SetupRecvStream();
3360 cricket::WebRtcVoiceMediaChannel* media_channel =
3361 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3362 // Call GetSources with |kSsrcY| which doesn't exist.
3363 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3364 EXPECT_EQ(0u, sources.size());
3365}
3366
stefan658910c2015-09-03 05:48:32 -07003367// Tests that the library initializes and shuts down properly.
3368TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003369 // If the VoiceEngine wants to gather available codecs early, that's fine but
3370 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003371 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003372 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003373 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003374 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003375 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003376 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003377 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003378 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003379 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003380 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003381 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3382 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003383 EXPECT_TRUE(channel != nullptr);
3384 delete channel;
solenbergff976312016-03-30 23:28:51 -07003385}
stefan658910c2015-09-03 05:48:32 -07003386
solenbergff976312016-03-30 23:28:51 -07003387// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003388TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3389 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003390 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003391 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003392 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003393 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003394 {
peaha9cc40b2017-06-29 08:32:09 -07003395 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003396 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003397 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003398 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003399 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003400 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003401 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003402 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003403 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003404 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3405 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3406 EXPECT_TRUE(channel != nullptr);
3407 delete channel;
3408 }
stefan658910c2015-09-03 05:48:32 -07003409}
3410
ossu20a4b3f2017-04-27 02:08:52 -07003411// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3412TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003413 // TODO(ossu): Why are the payload types of codecs with non-static payload
3414 // type assignments checked here? It shouldn't really matter.
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();
solenberg2779bab2016-11-17 04:45:19 -08003422 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003423 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3424 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3425 (clockrate == 0 || codec.clockrate == clockrate);
3426 };
3427 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003428 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003429 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003430 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003431 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003432 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003433 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003434 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003435 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003436 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003437 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003438 EXPECT_EQ(126, codec.id);
3439 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3440 // Remove these checks once both send and receive side assigns payload types
3441 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003442 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003443 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003444 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003445 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003446 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003447 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003448 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003449 EXPECT_EQ(111, codec.id);
3450 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3451 EXPECT_EQ("10", codec.params.find("minptime")->second);
3452 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3453 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003454 }
3455 }
stefan658910c2015-09-03 05:48:32 -07003456}
3457
3458// Tests that VoE supports at least 32 channels
3459TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003460 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003461 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003462 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003463 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003464 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003465 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003466 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003467 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003468 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003469 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003470
3471 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003472 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003473 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003474 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3475 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003476 if (!channel)
3477 break;
stefan658910c2015-09-03 05:48:32 -07003478 channels[num_channels++] = channel;
3479 }
3480
Mirko Bonadeif859e552018-05-30 15:31:29 +02003481 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003482 EXPECT_EQ(expected, num_channels);
3483
3484 while (num_channels > 0) {
3485 delete channels[--num_channels];
3486 }
stefan658910c2015-09-03 05:48:32 -07003487}
3488
3489// Test that we set our preferred codecs properly.
3490TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003491 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3492 // - Check that our builtin codecs are usable by Channel.
3493 // - The codecs provided by the engine is usable by Channel.
3494 // It does not check that the codecs in the RecvParameters are actually
3495 // what we sent in - though it's probably reasonable to expect so, if
3496 // SetRecvParameters returns true.
3497 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003498 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003499 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003500 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003501 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003502 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003503 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003504 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003505 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003506 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003507 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003508 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3509 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003510 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003511 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003512 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003513}
ossu9def8002017-02-09 05:14:32 -08003514
3515TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3516 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003517 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3518 {48000, 2, 16000, 10000, 20000}};
3519 spec1.info.allow_comfort_noise = false;
3520 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003521 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003522 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3523 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003524 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003525 specs.push_back(webrtc::AudioCodecSpec{
3526 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3527 {16000, 1, 13300}});
3528 specs.push_back(
3529 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3530 specs.push_back(
3531 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003532
ossueb1fde42017-05-02 06:46:30 -07003533 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3534 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3535 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003536 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003537 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003538 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003539 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003540
peaha9cc40b2017-06-29 08:32:09 -07003541 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003542 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003543 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003544 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003545 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003546 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003547 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003548
3549 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3550 // check the actual values safely, to provide better test results.
3551 auto get_codec =
3552 [&codecs](size_t index) -> const cricket::AudioCodec& {
3553 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3554 if (codecs.size() > index)
3555 return codecs[index];
3556 return missing_codec;
3557 };
3558
3559 // Ensure the general codecs are generated first and in order.
3560 for (size_t i = 0; i != specs.size(); ++i) {
3561 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3562 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3563 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3564 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3565 }
3566
3567 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003568 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003569 auto find_codec =
3570 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3571 for (size_t i = 0; i != codecs.size(); ++i) {
3572 const cricket::AudioCodec& codec = codecs[i];
3573 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3574 codec.clockrate == format.clockrate_hz &&
3575 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003576 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003577 }
3578 }
3579 return -1;
3580 };
3581
3582 // Ensure all supplementary codecs are generated last. Their internal ordering
3583 // is not important.
3584 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3585 const int num_specs = static_cast<int>(specs.size());
3586 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3587 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3588 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3589 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3590 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3591 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3592 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3593}