blob: b03af34661c4de05bbf1d4d6e110359774c38097 [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
Danil Chapovalov00c71832018-06-15 15:58:38 +0200389 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700390 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700391 }
392
Danil Chapovalov00c71832018-06-15 15:58:38 +0200393 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
394 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700395 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
396 }
397
skvlade0d46372016-04-07 22:59:22 -0700398 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
399 int global_max,
400 int stream_max,
401 bool expected_result,
402 int expected_codec_bitrate) {
403 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800404 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700405
406 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700407 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800408 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700409
410 // Verify that reading back the parameters gives results
411 // consistent with the Set() result.
412 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800413 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700414 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
415 EXPECT_EQ(expected_result ? stream_max : -1,
416 resulting_parameters.encodings[0].max_bitrate_bps);
417
418 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800419 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700420 }
421
stefan13f1a0a2016-11-30 07:22:58 -0800422 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
423 int expected_min_bitrate_bps,
424 const char* start_bitrate_kbps,
425 int expected_start_bitrate_bps,
426 const char* max_bitrate_kbps,
427 int expected_max_bitrate_bps) {
428 EXPECT_TRUE(SetupSendStream());
429 auto& codecs = send_parameters_.codecs;
430 codecs.clear();
431 codecs.push_back(kOpusCodec);
432 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
433 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100435 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
436 SetSdpBitrateParameters(
437 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
438 expected_min_bitrate_bps),
439 Field(&BitrateConstraints::start_bitrate_bps,
440 expected_start_bitrate_bps),
441 Field(&BitrateConstraints::max_bitrate_bps,
442 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800443
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100444 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800445 }
446
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000447 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700448 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
453 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(
455 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700461 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800462 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 // Ensure extension is set properly.
465 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700466 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700467 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
solenberg7add0582015-11-20 09:59:34 -0800472 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800474 cricket::StreamParams::CreateLegacy(kSsrcY)));
475 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
476 call_.GetAudioSendStream(kSsrcY));
477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200482 send_parameters_.codecs.push_back(kPcmuCodec);
483 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 }
488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700490 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
495 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(
497 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800498 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800502 recv_parameters_.extensions.clear();
503 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 // Ensure extension is set properly.
507 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700508 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800509 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
511 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
solenberg7add0582015-11-20 09:59:34 -0800514 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_TRUE(AddRecvStream(kSsrcY));
516 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
517 call_.GetAudioReceiveStream(kSsrcY));
518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521
522 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800523 recv_parameters_.extensions.clear();
524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000527 }
528
solenberg85a04962015-10-27 03:35:21 -0700529 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
530 webrtc::AudioSendStream::Stats stats;
531 stats.local_ssrc = 12;
532 stats.bytes_sent = 345;
533 stats.packets_sent = 678;
534 stats.packets_lost = 9012;
535 stats.fraction_lost = 34.56f;
536 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100537 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700538 stats.ext_seqnum = 789;
539 stats.jitter_ms = 12;
540 stats.rtt_ms = 345;
541 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100542 stats.apm_statistics.delay_median_ms = 234;
543 stats.apm_statistics.delay_standard_deviation_ms = 567;
544 stats.apm_statistics.echo_return_loss = 890;
545 stats.apm_statistics.echo_return_loss_enhancement = 1234;
546 stats.apm_statistics.residual_echo_likelihood = 0.432f;
547 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100548 stats.ana_statistics.bitrate_action_counter = 321;
549 stats.ana_statistics.channel_action_counter = 432;
550 stats.ana_statistics.dtx_action_counter = 543;
551 stats.ana_statistics.fec_action_counter = 654;
552 stats.ana_statistics.frame_length_increase_counter = 765;
553 stats.ana_statistics.frame_length_decrease_counter = 876;
554 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700555 stats.typing_noise_detected = true;
556 return stats;
557 }
558 void SetAudioSendStreamStats() {
559 for (auto* s : call_.GetAudioSendStreams()) {
560 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200561 }
solenberg85a04962015-10-27 03:35:21 -0700562 }
solenberg566ef242015-11-06 15:34:49 -0800563 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
564 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700565 const auto stats = GetAudioSendStreamStats();
566 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
567 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
568 EXPECT_EQ(info.packets_sent, stats.packets_sent);
569 EXPECT_EQ(info.packets_lost, stats.packets_lost);
570 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
571 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800572 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700573 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
574 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
575 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
576 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100577 EXPECT_EQ(info.apm_statistics.delay_median_ms,
578 stats.apm_statistics.delay_median_ms);
579 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
580 stats.apm_statistics.delay_standard_deviation_ms);
581 EXPECT_EQ(info.apm_statistics.echo_return_loss,
582 stats.apm_statistics.echo_return_loss);
583 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
584 stats.apm_statistics.echo_return_loss_enhancement);
585 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
586 stats.apm_statistics.residual_echo_likelihood);
587 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
588 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700589 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
590 stats.ana_statistics.bitrate_action_counter);
591 EXPECT_EQ(info.ana_statistics.channel_action_counter,
592 stats.ana_statistics.channel_action_counter);
593 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
594 stats.ana_statistics.dtx_action_counter);
595 EXPECT_EQ(info.ana_statistics.fec_action_counter,
596 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700597 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
598 stats.ana_statistics.frame_length_increase_counter);
599 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
600 stats.ana_statistics.frame_length_decrease_counter);
601 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
602 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800603 EXPECT_EQ(info.typing_noise_detected,
604 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700605 }
606
607 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
608 webrtc::AudioReceiveStream::Stats stats;
609 stats.remote_ssrc = 123;
610 stats.bytes_rcvd = 456;
611 stats.packets_rcvd = 768;
612 stats.packets_lost = 101;
613 stats.fraction_lost = 23.45f;
614 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100615 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700616 stats.ext_seqnum = 678;
617 stats.jitter_ms = 901;
618 stats.jitter_buffer_ms = 234;
619 stats.jitter_buffer_preferred_ms = 567;
620 stats.delay_estimate_ms = 890;
621 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700622 stats.total_samples_received = 5678901;
623 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200624 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200625 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700626 stats.expand_rate = 5.67f;
627 stats.speech_expand_rate = 8.90f;
628 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200629 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700630 stats.accelerate_rate = 4.56f;
631 stats.preemptive_expand_rate = 7.89f;
632 stats.decoding_calls_to_silence_generator = 12;
633 stats.decoding_calls_to_neteq = 345;
634 stats.decoding_normal = 67890;
635 stats.decoding_plc = 1234;
636 stats.decoding_cng = 5678;
637 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700638 stats.decoding_muted_output = 3456;
639 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200640 return stats;
641 }
642 void SetAudioReceiveStreamStats() {
643 for (auto* s : call_.GetAudioReceiveStreams()) {
644 s->SetStats(GetAudioReceiveStreamStats());
645 }
646 }
647 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700648 const auto stats = GetAudioReceiveStreamStats();
649 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
650 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200651 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
652 stats.packets_rcvd);
653 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
654 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700655 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
656 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800657 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200658 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
659 stats.ext_seqnum);
660 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
661 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
662 stats.jitter_buffer_ms);
663 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700664 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200665 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
666 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700667 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700668 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
669 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200670 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200671 EXPECT_EQ(info.jitter_buffer_delay_seconds,
672 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.expand_rate, stats.expand_rate);
674 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
675 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200676 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700677 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
678 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200679 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700680 stats.decoding_calls_to_silence_generator);
681 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
682 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
683 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
684 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
685 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700686 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700687 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200688 }
hbos1acfbd22016-11-17 23:43:29 -0800689 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
690 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
691 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
692 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
693 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
694 codec.ToCodecParameters());
695 }
696 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
697 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
698 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
699 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
700 codec.ToCodecParameters());
701 }
702 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200703
peah8271d042016-11-22 07:24:52 -0800704 bool IsHighPassFilterEnabled() {
705 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
706 }
707
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700709 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700710 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800711 webrtc::test::MockGainControl& apm_gc_;
712 webrtc::test::MockEchoCancellation& apm_ec_;
713 webrtc::test::MockNoiseSuppression& apm_ns_;
714 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200715 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700716 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700717 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200718 cricket::AudioSendParameters send_parameters_;
719 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800720 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700721 webrtc::AudioProcessing::Config apm_config_;
722
stefanba4c0e42016-02-04 04:12:24 -0800723 private:
724 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725};
726
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727// Tests that we can create and destroy a channel.
728TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700729 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730}
731
solenberg31fec402016-05-06 02:13:12 -0700732// Test that we can add a send stream and that it has the correct defaults.
733TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
734 EXPECT_TRUE(SetupChannel());
735 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800736 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
737 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
738 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700739 EXPECT_EQ("", config.rtp.c_name);
740 EXPECT_EQ(0u, config.rtp.extensions.size());
741 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
742 config.send_transport);
743}
744
745// Test that we can add a receive stream and that it has the correct defaults.
746TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
747 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800748 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700749 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800750 GetRecvStreamConfig(kSsrcX);
751 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700752 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
753 EXPECT_FALSE(config.rtp.transport_cc);
754 EXPECT_EQ(0u, config.rtp.extensions.size());
755 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
756 config.rtcp_send_transport);
757 EXPECT_EQ("", config.sync_group);
758}
759
stefanba4c0e42016-02-04 04:12:24 -0800760TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700761 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800762 bool opus_found = false;
763 for (cricket::AudioCodec codec : codecs) {
764 if (codec.name == "opus") {
765 EXPECT_TRUE(HasTransportCc(codec));
766 opus_found = true;
767 }
768 }
769 EXPECT_TRUE(opus_found);
770}
771
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772// Test that we set our inbound codecs properly, including changing PT.
773TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700774 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 cricket::AudioRecvParameters parameters;
776 parameters.codecs.push_back(kIsacCodec);
777 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800778 parameters.codecs.push_back(kTelephoneEventCodec1);
779 parameters.codecs.push_back(kTelephoneEventCodec2);
780 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200781 parameters.codecs[2].id = 126;
782 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800783 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700784 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
785 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
786 {{0, {"PCMU", 8000, 1}},
787 {106, {"ISAC", 16000, 1}},
788 {126, {"telephone-event", 8000, 1}},
789 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
792// Test that we fail to set an unknown inbound codec.
793TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700794 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 cricket::AudioRecvParameters parameters;
796 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700797 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799}
800
801// Test that we fail if we have duplicate types in the inbound list.
802TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700803 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200804 cricket::AudioRecvParameters parameters;
805 parameters.codecs.push_back(kIsacCodec);
806 parameters.codecs.push_back(kCn16000Codec);
807 parameters.codecs[1].id = kIsacCodec.id;
808 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that we can decode OPUS without stereo parameters.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kPcmuCodec);
817 parameters.codecs.push_back(kOpusCodec);
818 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800819 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700820 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
821 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
822 {{0, {"PCMU", 8000, 1}},
823 {103, {"ISAC", 16000, 1}},
824 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825}
826
827// Test that we can decode OPUS with stereo = 0.
828TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700829 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 cricket::AudioRecvParameters parameters;
831 parameters.codecs.push_back(kIsacCodec);
832 parameters.codecs.push_back(kPcmuCodec);
833 parameters.codecs.push_back(kOpusCodec);
834 parameters.codecs[2].params["stereo"] = "0";
835 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800836 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700837 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
838 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
839 {{0, {"PCMU", 8000, 1}},
840 {103, {"ISAC", 16000, 1}},
841 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842}
843
844// Test that we can decode OPUS with stereo = 1.
845TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700846 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200847 cricket::AudioRecvParameters parameters;
848 parameters.codecs.push_back(kIsacCodec);
849 parameters.codecs.push_back(kPcmuCodec);
850 parameters.codecs.push_back(kOpusCodec);
851 parameters.codecs[2].params["stereo"] = "1";
852 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800853 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700854 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
855 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
856 {{0, {"PCMU", 8000, 1}},
857 {103, {"ISAC", 16000, 1}},
858 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859}
860
861// Test that changes to recv codecs are applied to all streams.
862TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700863 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 cricket::AudioRecvParameters parameters;
865 parameters.codecs.push_back(kIsacCodec);
866 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800867 parameters.codecs.push_back(kTelephoneEventCodec1);
868 parameters.codecs.push_back(kTelephoneEventCodec2);
869 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200870 parameters.codecs[2].id = 126;
871 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700872 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
873 EXPECT_TRUE(AddRecvStream(ssrc));
874 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
875 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
876 {{0, {"PCMU", 8000, 1}},
877 {106, {"ISAC", 16000, 1}},
878 {126, {"telephone-event", 8000, 1}},
879 {107, {"telephone-event", 32000, 1}}})));
880 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881}
882
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800887 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889
solenberg2100c0b2017-03-01 11:29:29 -0800890 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200891 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800892 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893}
894
895// Test that we can apply the same set of codecs again while playing.
896TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700897 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 cricket::AudioRecvParameters parameters;
899 parameters.codecs.push_back(kIsacCodec);
900 parameters.codecs.push_back(kCn16000Codec);
901 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700902 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
deadbeefcb383672017-04-26 16:28:42 -0700905 // Remapping a payload type to a different codec should fail.
906 parameters.codecs[0] = kOpusCodec;
907 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800909 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910}
911
912// Test that we can add a codec while playing.
913TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700914 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 cricket::AudioRecvParameters parameters;
916 parameters.codecs.push_back(kIsacCodec);
917 parameters.codecs.push_back(kCn16000Codec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700919 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200921 parameters.codecs.push_back(kOpusCodec);
922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
deadbeefcb383672017-04-26 16:28:42 -0700926// Test that we accept adding the same codec with a different payload type.
927// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
928TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
929 EXPECT_TRUE(SetupRecvStream());
930 cricket::AudioRecvParameters parameters;
931 parameters.codecs.push_back(kIsacCodec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
933
934 ++parameters.codecs[0].id;
935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
936}
937
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000941 // Test that when autobw is enabled, bitrate is kept as the default
942 // value. autobw is enabled for the following tests because the target
943 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
945 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700946 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947
948 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700949 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950
ossu20a4b3f2017-04-27 02:08:52 -0700951 // opus, default bitrate == 32000 in mono.
952 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953}
954
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
960 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700961 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
965 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
966 // Rates above the max (510000) should be capped.
967 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000970TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000972
973 // Test that we can only set a maximum bitrate for a fixed-rate codec
974 // if it's bigger than the fixed rate.
975
976 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700977 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
983 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984}
985
986TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700987 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200988 const int kDesiredBitrate = 128000;
989 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700990 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200991 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700992 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000993
994 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800995 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000996
solenberg2100c0b2017-03-01 11:29:29 -0800997 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000998}
999
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000// Test that bitrate cannot be set for CBR codecs.
1001// Bitrate is ignored if it is higher than the fixed bitrate.
1002// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001003TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001004 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005
1006 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009
1010 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001011 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001013
1014 send_parameters_.max_bandwidth_bps = 128;
1015 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001016 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017}
1018
skvlade0d46372016-04-07 22:59:22 -07001019// Test that the per-stream bitrate limit and the global
1020// bitrate limit both apply.
1021TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1022 EXPECT_TRUE(SetupSendStream());
1023
ossu20a4b3f2017-04-27 02:08:52 -07001024 // opus, default bitrate == 32000.
1025 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1028 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1029
1030 // CBR codecs allow both maximums to exceed the bitrate.
1031 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1035
1036 // CBR codecs don't allow per stream maximums to be too low.
1037 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1038 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1039}
1040
1041// Test that an attempt to set RtpParameters for a stream that does not exist
1042// fails.
1043TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1044 EXPECT_TRUE(SetupChannel());
1045 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001046 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001047 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001048
1049 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001050 EXPECT_FALSE(
1051 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001052}
1053
1054TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001055 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001056 // This test verifies that setting RtpParameters succeeds only if
1057 // the structure contains exactly one encoding.
1058 // TODO(skvlad): Update this test when we start supporting setting parameters
1059 // for each encoding individually.
1060
1061 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001062 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001063 // Two or more encodings should result in failure.
1064 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001065 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001066 // Zero encodings should also fail.
1067 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001068 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001069}
1070
1071// Changing the SSRC through RtpParameters is not allowed.
1072TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1073 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001074 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001075 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001076 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001077}
1078
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001080// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001081TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1082 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001083 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001084 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001086 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087 ASSERT_EQ(1u, parameters.encodings.size());
1088 ASSERT_TRUE(parameters.encodings[0].active);
1089 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001090 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001091 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092
1093 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001094 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001096 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001097 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001098 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099}
1100
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001101// Test that SetRtpSendParameters configures the correct encoding channel for
1102// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001103TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1104 SetupForMultiSendStream();
1105 // Create send streams.
1106 for (uint32_t ssrc : kSsrcs4) {
1107 EXPECT_TRUE(
1108 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1109 }
1110 // Configure one stream to be limited by the stream config, another to be
1111 // limited by the global max, and the third one with no per-stream limit
1112 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001113 SetGlobalMaxBitrate(kOpusCodec, 32000);
1114 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1115 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001116 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1117
ossu20a4b3f2017-04-27 02:08:52 -07001118 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1119 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1120 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001121
1122 // Remove the global cap; the streams should switch to their respective
1123 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001124 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001125 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1126 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1127 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001128}
1129
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001130// Test that GetRtpSendParameters returns the currently configured codecs.
1131TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132 EXPECT_TRUE(SetupSendStream());
1133 cricket::AudioSendParameters parameters;
1134 parameters.codecs.push_back(kIsacCodec);
1135 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001136 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137
solenberg2100c0b2017-03-01 11:29:29 -08001138 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001139 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1141 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142}
1143
Florent Castellidacec712018-05-24 16:24:21 +02001144// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1145TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1146 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1147 params.cname = "rtcpcname";
1148 EXPECT_TRUE(SetupSendStream(params));
1149
1150 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1151 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1152}
1153
Florent Castelliabe301f2018-06-12 18:33:49 +02001154TEST_F(WebRtcVoiceEngineTestFake,
1155 DetectRtpSendParameterHeaderExtensionsChange) {
1156 EXPECT_TRUE(SetupSendStream());
1157
1158 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1159 rtp_parameters.header_extensions.emplace_back();
1160
1161 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1162
1163 webrtc::RTCError result =
1164 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1165 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1166}
1167
deadbeefcb443432016-12-12 11:12:36 -08001168// Test that GetRtpSendParameters returns an SSRC.
1169TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1170 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001171 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001172 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001173 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001174}
1175
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001177TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001178 EXPECT_TRUE(SetupSendStream());
1179 cricket::AudioSendParameters parameters;
1180 parameters.codecs.push_back(kIsacCodec);
1181 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001182 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001183
solenberg2100c0b2017-03-01 11:29:29 -08001184 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001185
1186 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001187 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001188
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001189 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001190 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1191 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001192}
1193
minyuececec102017-03-27 13:04:25 -07001194// Test that max_bitrate_bps in send stream config gets updated correctly when
1195// SetRtpSendParameters is called.
1196TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1197 webrtc::test::ScopedFieldTrials override_field_trials(
1198 "WebRTC-Audio-SendSideBwe/Enabled/");
1199 EXPECT_TRUE(SetupSendStream());
1200 cricket::AudioSendParameters send_parameters;
1201 send_parameters.codecs.push_back(kOpusCodec);
1202 SetSendParameters(send_parameters);
1203
1204 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1205 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1206 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1207
1208 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001209 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001210 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001211
1212 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1213 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1214}
1215
Seth Hampson24722b32017-12-22 09:36:42 -08001216// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1217// a value <= 0, setting the parameters returns false.
1218TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1219 EXPECT_TRUE(SetupSendStream());
1220 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1221 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1222 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1223 rtp_parameters.encodings[0].bitrate_priority);
1224
1225 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001226 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001227 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001228 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001229}
1230
1231// Test that the bitrate_priority in the send stream config gets updated when
1232// SetRtpSendParameters is set for the VoiceMediaChannel.
1233TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1234 EXPECT_TRUE(SetupSendStream());
1235 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1236
1237 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1238 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1239 rtp_parameters.encodings[0].bitrate_priority);
1240 double new_bitrate_priority = 2.0;
1241 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001242 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001243
1244 // The priority should get set for both the audio channel's rtp parameters
1245 // and the audio send stream's audio config.
1246 EXPECT_EQ(
1247 new_bitrate_priority,
1248 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1249 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1250}
1251
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252// Test that GetRtpReceiveParameters returns the currently configured codecs.
1253TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1254 EXPECT_TRUE(SetupRecvStream());
1255 cricket::AudioRecvParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
1258 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1259
1260 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001261 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001262 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1263 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1264 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1265}
1266
deadbeefcb443432016-12-12 11:12:36 -08001267// Test that GetRtpReceiveParameters returns an SSRC.
1268TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1269 EXPECT_TRUE(SetupRecvStream());
1270 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001271 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001272 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001273 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001274}
1275
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001276// Test that if we set/get parameters multiple times, we get the same results.
1277TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1278 EXPECT_TRUE(SetupRecvStream());
1279 cricket::AudioRecvParameters parameters;
1280 parameters.codecs.push_back(kIsacCodec);
1281 parameters.codecs.push_back(kPcmuCodec);
1282 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1283
1284 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001285 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001286
1287 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001288 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001289
1290 // ... And this shouldn't change the params returned by
1291 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001292 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1293 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001294}
1295
deadbeef3bc15102017-04-20 19:25:07 -07001296// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1297// aren't signaled. It should return an empty "RtpEncodingParameters" when
1298// configured to receive an unsignaled stream and no packets have been received
1299// yet, and start returning the SSRC once a packet has been received.
1300TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1301 ASSERT_TRUE(SetupChannel());
1302 // Call necessary methods to configure receiving a default stream as
1303 // soon as it arrives.
1304 cricket::AudioRecvParameters parameters;
1305 parameters.codecs.push_back(kIsacCodec);
1306 parameters.codecs.push_back(kPcmuCodec);
1307 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1308
1309 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1310 // stream. Should return nothing.
1311 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1312
1313 // Set a sink for an unsignaled stream.
1314 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1315 // Value of "0" means "unsignaled stream".
1316 channel_->SetRawAudioSink(0, std::move(fake_sink));
1317
1318 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1319 // in this method means "unsignaled stream".
1320 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1321 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1322 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1323
1324 // Receive PCMU packet (SSRC=1).
1325 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1326
1327 // The |ssrc| member should still be unset.
1328 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1329 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1330 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1331}
1332
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333// Test that we apply codecs properly.
1334TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001335 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001336 cricket::AudioSendParameters parameters;
1337 parameters.codecs.push_back(kIsacCodec);
1338 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001339 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001341 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001342 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001343 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1344 EXPECT_EQ(96, send_codec_spec.payload_type);
1345 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1346 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1347 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001348 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001349 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350}
1351
ossu20a4b3f2017-04-27 02:08:52 -07001352// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1353// AudioSendStream.
1354TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001355 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001356 cricket::AudioSendParameters parameters;
1357 parameters.codecs.push_back(kIsacCodec);
1358 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001359 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 parameters.codecs[0].id = 96;
1361 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001362 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001363 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001364 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001365 // Calling SetSendCodec again with same codec which is already set.
1366 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001367 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001368 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001369}
1370
ossu20a4b3f2017-04-27 02:08:52 -07001371// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1372// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001373
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001374// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001376 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 cricket::AudioSendParameters parameters;
1378 parameters.codecs.push_back(kOpusCodec);
1379 parameters.codecs[0].bitrate = 0;
1380 parameters.codecs[0].clockrate = 50000;
1381 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382}
1383
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001384// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].channels = 0;
1391 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392}
1393
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001394// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].bitrate = 0;
1400 parameters.codecs[0].channels = 0;
1401 parameters.codecs[0].params["stereo"] = "1";
1402 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403}
1404
1405// Test that if channel is 1 for opus and there's no stereo, we fail.
1406TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001407 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001408 cricket::AudioSendParameters parameters;
1409 parameters.codecs.push_back(kOpusCodec);
1410 parameters.codecs[0].bitrate = 0;
1411 parameters.codecs[0].channels = 1;
1412 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413}
1414
1415// Test that if channel is 1 for opus and stereo=0, we fail.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 0;
1421 parameters.codecs[0].channels = 1;
1422 parameters.codecs[0].params["stereo"] = "0";
1423 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424}
1425
1426// Test that if channel is 1 for opus and stereo=1, we fail.
1427TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001428 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 cricket::AudioSendParameters parameters;
1430 parameters.codecs.push_back(kOpusCodec);
1431 parameters.codecs[0].bitrate = 0;
1432 parameters.codecs[0].channels = 1;
1433 parameters.codecs[0].params["stereo"] = "1";
1434 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435}
1436
ossu20a4b3f2017-04-27 02:08:52 -07001437// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001439 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 cricket::AudioSendParameters parameters;
1441 parameters.codecs.push_back(kOpusCodec);
1442 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001444 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].bitrate = 0;
1453 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001454 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001455 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456}
1457
ossu20a4b3f2017-04-27 02:08:52 -07001458// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001459TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001460 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001461 cricket::AudioSendParameters parameters;
1462 parameters.codecs.push_back(kOpusCodec);
1463 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001464 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001465 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001466 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001467 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001468
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001469 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001470 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001471 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001472}
1473
ossu20a4b3f2017-04-27 02:08:52 -07001474// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001476 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 cricket::AudioSendParameters parameters;
1478 parameters.codecs.push_back(kOpusCodec);
1479 parameters.codecs[0].bitrate = 0;
1480 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001481 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001482 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001483}
1484
ossu20a4b3f2017-04-27 02:08:52 -07001485// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001487 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001488 cricket::AudioSendParameters parameters;
1489 parameters.codecs.push_back(kOpusCodec);
1490 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001491 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001492 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001493 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001494 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001495
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001496 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001497 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001498 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001499}
1500
ossu20a4b3f2017-04-27 02:08:52 -07001501// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001502TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001503 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001504 cricket::AudioSendParameters parameters;
1505 parameters.codecs.push_back(kOpusCodec);
1506 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1509 EXPECT_EQ(111, spec.payload_type);
1510 EXPECT_EQ(96000, spec.target_bitrate_bps);
1511 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001512 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001513 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
ossu20a4b3f2017-04-27 02:08:52 -07001516// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].bitrate = 30000;
1522 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001524 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001525}
1526
ossu20a4b3f2017-04-27 02:08:52 -07001527// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001529 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001530 cricket::AudioSendParameters parameters;
1531 parameters.codecs.push_back(kOpusCodec);
1532 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].bitrate = 30000;
1543 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001544 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001545 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001546}
1547
stefan13f1a0a2016-11-30 07:22:58 -08001548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1549 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1550 200000);
1551}
1552
1553TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1554 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1555}
1556
1557TEST_F(WebRtcVoiceEngineTestFake,
1558 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1559 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1560}
1561
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1563 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1564}
1565
1566TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001567 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001568 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1569 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001570 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001571 // Setting max bitrate should keep previous min bitrate
1572 // Setting max bitrate should not reset start bitrate.
1573 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1574 SetSdpBitrateParameters(
1575 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1576 Field(&BitrateConstraints::start_bitrate_bps, -1),
1577 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001578 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001579}
1580
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001581// Test that we can enable NACK with opus as caller.
1582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001583 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001584 cricket::AudioSendParameters parameters;
1585 parameters.codecs.push_back(kOpusCodec);
1586 parameters.codecs[0].AddFeedbackParam(
1587 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1588 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001589 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001594// Test that we can enable NACK with opus as callee.
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001597 cricket::AudioSendParameters parameters;
1598 parameters.codecs.push_back(kOpusCodec);
1599 parameters.codecs[0].AddFeedbackParam(
1600 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1601 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001602 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001604 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001606
1607 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001608 cricket::StreamParams::CreateLegacy(kSsrcX)));
1609 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001610}
1611
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612// Test that we can enable NACK on receive streams.
1613TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001614 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
1618 parameters.codecs[0].AddFeedbackParam(
1619 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1620 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001621 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1622 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1625 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626}
1627
1628// Test that we can disable NACK.
1629TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001630 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001631 cricket::AudioSendParameters parameters;
1632 parameters.codecs.push_back(kOpusCodec);
1633 parameters.codecs[0].AddFeedbackParam(
1634 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1635 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001636 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001637 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001638
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001639 parameters.codecs.clear();
1640 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643}
1644
1645// Test that we can disable NACK on receive streams.
1646TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001647 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001648 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001649 cricket::AudioSendParameters parameters;
1650 parameters.codecs.push_back(kOpusCodec);
1651 parameters.codecs[0].AddFeedbackParam(
1652 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1653 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001655 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1656 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001657
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 parameters.codecs.clear();
1659 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1662 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001663}
1664
1665// Test that NACK is enabled on a new receive stream.
1666TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001667 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001668 cricket::AudioSendParameters parameters;
1669 parameters.codecs.push_back(kIsacCodec);
1670 parameters.codecs.push_back(kCn16000Codec);
1671 parameters.codecs[0].AddFeedbackParam(
1672 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1673 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001674 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001676
solenberg2100c0b2017-03-01 11:29:29 -08001677 EXPECT_TRUE(AddRecvStream(kSsrcY));
1678 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1679 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1680 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681}
1682
stefanba4c0e42016-02-04 04:12:24 -08001683TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001684 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001685 cricket::AudioSendParameters send_parameters;
1686 send_parameters.codecs.push_back(kOpusCodec);
1687 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001688 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001689
1690 cricket::AudioRecvParameters recv_parameters;
1691 recv_parameters.codecs.push_back(kIsacCodec);
1692 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_TRUE(AddRecvStream(kSsrcX));
1694 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001695 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001696 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001697
ossudedfd282016-06-14 07:12:39 -07001698 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001699 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001700 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001701 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001702 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001703}
1704
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001705// Test that we can switch back and forth between Opus and ISAC with CN.
1706TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001707 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001708
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 cricket::AudioSendParameters opus_parameters;
1710 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001712 {
ossu20a4b3f2017-04-27 02:08:52 -07001713 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1714 EXPECT_EQ(111, spec.payload_type);
1715 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001716 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 cricket::AudioSendParameters isac_parameters;
1719 isac_parameters.codecs.push_back(kIsacCodec);
1720 isac_parameters.codecs.push_back(kCn16000Codec);
1721 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001723 {
ossu20a4b3f2017-04-27 02:08:52 -07001724 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1725 EXPECT_EQ(103, spec.payload_type);
1726 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001727 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001728
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001730 {
ossu20a4b3f2017-04-27 02:08:52 -07001731 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1732 EXPECT_EQ(111, spec.payload_type);
1733 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001734 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735}
1736
1737// Test that we handle various ways of specifying bitrate.
1738TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001739 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 cricket::AudioSendParameters parameters;
1741 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001742 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001743 {
ossu20a4b3f2017-04-27 02:08:52 -07001744 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1745 EXPECT_EQ(103, spec.payload_type);
1746 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1747 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001748 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001749
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001750 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001752 {
ossu20a4b3f2017-04-27 02:08:52 -07001753 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1754 EXPECT_EQ(103, spec.payload_type);
1755 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1756 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001757 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001760 {
ossu20a4b3f2017-04-27 02:08:52 -07001761 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1762 EXPECT_EQ(103, spec.payload_type);
1763 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1764 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001765 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001768 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001769 {
ossu20a4b3f2017-04-27 02:08:52 -07001770 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1771 EXPECT_EQ(0, spec.payload_type);
1772 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1773 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001774 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001778 {
ossu20a4b3f2017-04-27 02:08:52 -07001779 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1780 EXPECT_EQ(0, spec.payload_type);
1781 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1782 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001783 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001785 parameters.codecs[0] = kOpusCodec;
1786 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001788 {
ossu20a4b3f2017-04-27 02:08:52 -07001789 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1790 EXPECT_EQ(111, spec.payload_type);
1791 EXPECT_STREQ("opus", spec.format.name.c_str());
1792 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001793 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794}
1795
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001796// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001798 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001799 cricket::AudioSendParameters parameters;
1800 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001801}
1802
1803// Test that we can set send codecs even with telephone-event codec as the first
1804// one on the list.
1805TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001806 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001807 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001808 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001809 parameters.codecs.push_back(kIsacCodec);
1810 parameters.codecs.push_back(kPcmuCodec);
1811 parameters.codecs[0].id = 98; // DTMF
1812 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001813 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001814 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1815 EXPECT_EQ(96, spec.payload_type);
1816 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001817 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001818 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001819}
1820
Harald Alvestranda1f66612018-02-21 11:24:23 +01001821// Test that CanInsertDtmf() is governed by the send flag
1822TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1823 EXPECT_TRUE(SetupSendStream());
1824 cricket::AudioSendParameters parameters;
1825 parameters.codecs.push_back(kTelephoneEventCodec1);
1826 parameters.codecs.push_back(kPcmuCodec);
1827 parameters.codecs[0].id = 98; // DTMF
1828 parameters.codecs[1].id = 96;
1829 SetSendParameters(parameters);
1830 EXPECT_FALSE(channel_->CanInsertDtmf());
1831 SetSend(true);
1832 EXPECT_TRUE(channel_->CanInsertDtmf());
1833 SetSend(false);
1834 EXPECT_FALSE(channel_->CanInsertDtmf());
1835}
1836
solenberg31642aa2016-03-14 08:00:37 -07001837// Test that payload type range is limited for telephone-event codec.
1838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001840 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001841 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001842 parameters.codecs.push_back(kIsacCodec);
1843 parameters.codecs[0].id = 0; // DTMF
1844 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001845 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001846 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001847 EXPECT_TRUE(channel_->CanInsertDtmf());
1848 parameters.codecs[0].id = 128; // DTMF
1849 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1850 EXPECT_FALSE(channel_->CanInsertDtmf());
1851 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001852 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001853 EXPECT_TRUE(channel_->CanInsertDtmf());
1854 parameters.codecs[0].id = -1; // DTMF
1855 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1856 EXPECT_FALSE(channel_->CanInsertDtmf());
1857}
1858
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001859// Test that we can set send codecs even with CN codec as the first
1860// one on the list.
1861TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001862 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001863 cricket::AudioSendParameters parameters;
1864 parameters.codecs.push_back(kCn16000Codec);
1865 parameters.codecs.push_back(kIsacCodec);
1866 parameters.codecs.push_back(kPcmuCodec);
1867 parameters.codecs[0].id = 98; // wideband CN
1868 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001869 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001870 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1871 EXPECT_EQ(96, send_codec_spec.payload_type);
1872 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001873 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001874}
1875
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001876// Test that we set VAD and DTMF types correctly as caller.
1877TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001878 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001879 cricket::AudioSendParameters parameters;
1880 parameters.codecs.push_back(kIsacCodec);
1881 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001883 parameters.codecs.push_back(kCn16000Codec);
1884 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001885 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 parameters.codecs[0].id = 96;
1887 parameters.codecs[2].id = 97; // wideband CN
1888 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001890 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1891 EXPECT_EQ(96, send_codec_spec.payload_type);
1892 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001893 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001894 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001895 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001896 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897}
1898
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001899// Test that we set VAD and DTMF types correctly as callee.
1900TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001901 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001902 cricket::AudioSendParameters parameters;
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001905 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 parameters.codecs.push_back(kCn16000Codec);
1907 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001908 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 parameters.codecs[0].id = 96;
1910 parameters.codecs[2].id = 97; // wideband CN
1911 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001913 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001914 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001915
ossu20a4b3f2017-04-27 02:08:52 -07001916 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1917 EXPECT_EQ(96, send_codec_spec.payload_type);
1918 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001919 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001920 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001921 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001922 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001923}
1924
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925// Test that we only apply VAD if we have a CN codec that matches the
1926// send codec clockrate.
1927TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001928 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001929 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001930 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001931 parameters.codecs.push_back(kIsacCodec);
1932 parameters.codecs.push_back(kCn16000Codec);
1933 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001934 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001935 {
ossu20a4b3f2017-04-27 02:08:52 -07001936 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1937 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001938 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001939 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001940 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001941 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001942 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001943 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001944 {
ossu20a4b3f2017-04-27 02:08:52 -07001945 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1946 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001947 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001948 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001952 {
ossu20a4b3f2017-04-27 02:08:52 -07001953 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1954 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001955 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001956 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001957 }
Brave Yao5225dd82015-03-26 07:39:19 +08001958 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001961 {
ossu20a4b3f2017-04-27 02:08:52 -07001962 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1963 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001964 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966}
1967
1968// Test that we perform case-insensitive matching of codec names.
1969TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001971 cricket::AudioSendParameters parameters;
1972 parameters.codecs.push_back(kIsacCodec);
1973 parameters.codecs.push_back(kPcmuCodec);
1974 parameters.codecs.push_back(kCn16000Codec);
1975 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001976 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[0].name = "iSaC";
1978 parameters.codecs[0].id = 96;
1979 parameters.codecs[2].id = 97; // wideband CN
1980 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001981 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001982 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1983 EXPECT_EQ(96, send_codec_spec.payload_type);
1984 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001985 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001986 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001987 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001988 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001989}
1990
stefanba4c0e42016-02-04 04:12:24 -08001991class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1992 public:
1993 WebRtcVoiceEngineWithSendSideBweTest()
1994 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1995};
1996
1997TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1998 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001999 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002000 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002001 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2002 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2003 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002004 extension.id);
2005 return;
2006 }
2007 }
2008 FAIL() << "Transport sequence number extension not in header-extension list.";
2009}
2010
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002011// Test support for audio level header extension.
2012TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002013 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002014}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002015TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002016 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002017}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002018
solenbergd4adce42016-11-17 06:26:52 -08002019// Test support for transport sequence number header extension.
2020TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2021 TestSetSendRtpHeaderExtensions(
2022 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002023}
solenbergd4adce42016-11-17 06:26:52 -08002024TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2025 TestSetRecvRtpHeaderExtensions(
2026 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027}
2028
solenberg1ac56142015-10-13 03:58:19 -07002029// Test that we can create a channel and start sending on it.
2030TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002031 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002032 SetSendParameters(send_parameters_);
2033 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002034 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002035 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002036 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002037}
2038
2039// Test that a channel will send if and only if it has a source and is enabled
2040// for sending.
2041TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002042 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002043 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002044 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002045 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002046 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2047 SetAudioSend(kSsrcX, true, &fake_source_);
2048 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2049 SetAudioSend(kSsrcX, true, nullptr);
2050 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002051}
2052
solenberg94218532016-06-16 10:53:22 -07002053// Test that a channel is muted/unmuted.
2054TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2055 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002056 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002057 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2058 SetAudioSend(kSsrcX, true, nullptr);
2059 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2060 SetAudioSend(kSsrcX, false, nullptr);
2061 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002062}
2063
solenberg6d6e7c52016-04-13 09:07:30 -07002064// Test that SetSendParameters() does not alter a stream's send state.
2065TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2066 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002067 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002068
2069 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002070 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002072
2073 // Changing RTP header extensions will recreate the AudioSendStream.
2074 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002075 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002076 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002077 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002078
2079 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002080 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002082
2083 // Changing RTP header extensions will recreate the AudioSendStream.
2084 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002085 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002087}
2088
solenberg1ac56142015-10-13 03:58:19 -07002089// Test that we can create a channel and start playing out on it.
2090TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002091 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002092 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002093 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002094 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002095 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002096 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002097}
2098
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099// Test that we can add and remove send streams.
2100TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2101 SetupForMultiSendStream();
2102
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002104 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105
solenbergc96df772015-10-21 13:01:53 -07002106 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002108 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002109 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002111 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 }
tfarina5237aaf2015-11-10 23:44:30 -08002113 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114
solenbergc96df772015-10-21 13:01:53 -07002115 // Delete the send streams.
2116 for (uint32_t ssrc : kSsrcs4) {
2117 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002118 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002119 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120 }
solenbergc96df772015-10-21 13:01:53 -07002121 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122}
2123
2124// Test SetSendCodecs correctly configure the codecs in all send streams.
2125TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2126 SetupForMultiSendStream();
2127
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002129 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002131 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132 }
2133
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002134 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002136 parameters.codecs.push_back(kIsacCodec);
2137 parameters.codecs.push_back(kCn16000Codec);
2138 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002139 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140
2141 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002142 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002143 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2144 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002145 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2146 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002147 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002148 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149 }
2150
minyue7a973442016-10-20 03:27:12 -07002151 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002152 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002153 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002154 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002155 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2156 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002157 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2158 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002159 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002160 }
2161}
2162
2163// Test we can SetSend on all send streams correctly.
2164TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2165 SetupForMultiSendStream();
2166
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002167 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002168 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002169 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002170 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002171 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002172 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002173 }
2174
2175 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002176 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002177 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002178 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002179 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002180 }
2181
2182 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002183 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002184 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002185 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002186 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002187 }
2188}
2189
2190// Test we can set the correct statistics on all send streams.
2191TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2192 SetupForMultiSendStream();
2193
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002194 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002195 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002196 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002197 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002198 }
solenberg85a04962015-10-27 03:35:21 -07002199
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002200 // Create a receive stream to check that none of the send streams end up in
2201 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002202 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002203
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002204 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002205 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002206 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002207 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208
solenberg85a04962015-10-27 03:35:21 -07002209 // Check stats for the added streams.
2210 {
2211 cricket::VoiceMediaInfo info;
2212 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213
solenberg85a04962015-10-27 03:35:21 -07002214 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002215 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002216 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002217 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002218 }
hbos1acfbd22016-11-17 23:43:29 -08002219 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002220
2221 // We have added one receive stream. We should see empty stats.
2222 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002223 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002224 }
solenberg1ac56142015-10-13 03:58:19 -07002225
solenberg2100c0b2017-03-01 11:29:29 -08002226 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002227 {
2228 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002230 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002231 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002232 EXPECT_EQ(0u, info.receivers.size());
2233 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002234
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002235 // Deliver a new packet - a default receive stream should be created and we
2236 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002237 {
2238 cricket::VoiceMediaInfo info;
2239 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2240 SetAudioReceiveStreamStats();
2241 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002242 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002243 EXPECT_EQ(1u, info.receivers.size());
2244 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002245 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002246 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002247}
2248
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002249// Test that we can add and remove receive streams, and do proper send/playout.
2250// We can receive on multiple streams while sending one stream.
2251TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002252 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002253
solenberg1ac56142015-10-13 03:58:19 -07002254 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002255 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002256 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002257
solenberg1ac56142015-10-13 03:58:19 -07002258 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002259 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002260 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002261 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002262
solenberg1ac56142015-10-13 03:58:19 -07002263 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002265
2266 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002267 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2268 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2269 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002270
2271 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002272 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274
2275 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002276 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002277 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2278 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002279
aleloi84ef6152016-08-04 05:28:21 -07002280 // Restart playout and make sure recv streams are played out.
2281 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002282 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2283 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284
aleloi84ef6152016-08-04 05:28:21 -07002285 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2287 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288}
2289
wu@webrtc.org97077a32013-10-25 21:18:33 +00002290TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002291 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002292 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2293 .Times(1)
2294 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002295 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2296 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002297 send_parameters_.options.tx_agc_target_dbov = 3;
2298 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2299 send_parameters_.options.tx_agc_limiter = true;
2300 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002301 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2302 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2303 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002304 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002305}
2306
minyue6b825df2016-10-31 04:08:32 -07002307TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2308 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002309 send_parameters_.options.audio_network_adaptor = true;
2310 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002311 SetSendParameters(send_parameters_);
2312 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002313 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002314}
2315
2316TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2317 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002318 send_parameters_.options.audio_network_adaptor = true;
2319 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002320 SetSendParameters(send_parameters_);
2321 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002322 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002323 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002324 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002325 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002326 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002327}
2328
2329TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2330 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002331 send_parameters_.options.audio_network_adaptor = true;
2332 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002333 SetSendParameters(send_parameters_);
2334 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002335 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002336 const int initial_num = call_.GetNumCreatedSendStreams();
2337 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002338 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002339 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2340 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002341 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002342 // AudioSendStream not expected to be recreated.
2343 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2344 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002345 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002346}
2347
michaelt6672b262017-01-11 10:17:59 -08002348class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2349 : public WebRtcVoiceEngineTestFake {
2350 public:
2351 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2352 : WebRtcVoiceEngineTestFake(
2353 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2354 "Enabled/") {}
2355};
2356
2357TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2358 EXPECT_TRUE(SetupSendStream());
2359 cricket::AudioSendParameters parameters;
2360 parameters.codecs.push_back(kOpusCodec);
2361 SetSendParameters(parameters);
2362 const int initial_num = call_.GetNumCreatedSendStreams();
2363 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2364
2365 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2366 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002367 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2368 constexpr int kMinOverheadBps =
2369 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002370
2371 constexpr int kOpusMinBitrateBps = 6000;
2372 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002373 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002374 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002375 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002376 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002377
Oskar Sundbom78807582017-11-16 11:09:55 +01002378 parameters.options.audio_network_adaptor = true;
2379 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002380 SetSendParameters(parameters);
2381
ossu11bfc532017-02-16 05:37:06 -08002382 constexpr int kMinOverheadWithAnaBps =
2383 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002384
2385 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002386 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002387
minyuececec102017-03-27 13:04:25 -07002388 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002389 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002390}
2391
minyuececec102017-03-27 13:04:25 -07002392// This test is similar to
2393// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2394// additional field trial.
2395TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2396 SetRtpSendParameterUpdatesMaxBitrate) {
2397 EXPECT_TRUE(SetupSendStream());
2398 cricket::AudioSendParameters send_parameters;
2399 send_parameters.codecs.push_back(kOpusCodec);
2400 SetSendParameters(send_parameters);
2401
2402 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2403 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2404 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2405
2406 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002407 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002408 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002409
2410 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2411#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2412 constexpr int kMinOverhead = 3333;
2413#else
2414 constexpr int kMinOverhead = 6666;
2415#endif
2416 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2417}
2418
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002420// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002423 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424}
2425
2426TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2427 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002428 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002429 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002430 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002431 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002432 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002433 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002434 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435
solenberg85a04962015-10-27 03:35:21 -07002436 // Check stats for the added streams.
2437 {
2438 cricket::VoiceMediaInfo info;
2439 EXPECT_EQ(true, channel_->GetStats(&info));
2440
2441 // We have added one send stream. We should see the stats we've set.
2442 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002443 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002444 // We have added one receive stream. We should see empty stats.
2445 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002446 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002447 }
solenberg1ac56142015-10-13 03:58:19 -07002448
solenberg566ef242015-11-06 15:34:49 -08002449 // Start sending - this affects some reported stats.
2450 {
2451 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002452 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002453 EXPECT_EQ(true, channel_->GetStats(&info));
2454 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002455 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002456 }
2457
solenberg2100c0b2017-03-01 11:29:29 -08002458 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002459 {
2460 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002461 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002462 EXPECT_EQ(true, channel_->GetStats(&info));
2463 EXPECT_EQ(1u, info.senders.size());
2464 EXPECT_EQ(0u, info.receivers.size());
2465 }
solenberg1ac56142015-10-13 03:58:19 -07002466
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002467 // Deliver a new packet - a default receive stream should be created and we
2468 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002469 {
2470 cricket::VoiceMediaInfo info;
2471 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2472 SetAudioReceiveStreamStats();
2473 EXPECT_EQ(true, channel_->GetStats(&info));
2474 EXPECT_EQ(1u, info.senders.size());
2475 EXPECT_EQ(1u, info.receivers.size());
2476 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002477 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002478 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479}
2480
2481// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002482// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002484 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002485 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2486 EXPECT_TRUE(AddRecvStream(kSsrcY));
2487 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002488}
2489
2490// Test that the local SSRC is the same on sending and receiving channels if the
2491// receive channel is created before the send channel.
2492TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002493 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002494 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002496 cricket::StreamParams::CreateLegacy(kSsrcX)));
2497 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2498 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499}
2500
2501// Test that we can properly receive packets.
2502TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002503 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002504 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002506
2507 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2508 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509}
2510
2511// Test that we can properly receive packets on multiple streams.
2512TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002513 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002514 const uint32_t ssrc1 = 1;
2515 const uint32_t ssrc2 = 2;
2516 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002517 EXPECT_TRUE(AddRecvStream(ssrc1));
2518 EXPECT_TRUE(AddRecvStream(ssrc2));
2519 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002521 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002522 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002524 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002525 }
mflodman3d7db262016-04-29 00:57:13 -07002526
2527 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2528 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2529 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2530
2531 EXPECT_EQ(s1.received_packets(), 0);
2532 EXPECT_EQ(s2.received_packets(), 0);
2533 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002534
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002536 EXPECT_EQ(s1.received_packets(), 0);
2537 EXPECT_EQ(s2.received_packets(), 0);
2538 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002539
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002541 EXPECT_EQ(s1.received_packets(), 1);
2542 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2543 EXPECT_EQ(s2.received_packets(), 0);
2544 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002545
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002547 EXPECT_EQ(s1.received_packets(), 1);
2548 EXPECT_EQ(s2.received_packets(), 1);
2549 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2550 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002551
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002552 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002553 EXPECT_EQ(s1.received_packets(), 1);
2554 EXPECT_EQ(s2.received_packets(), 1);
2555 EXPECT_EQ(s3.received_packets(), 1);
2556 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002557
mflodman3d7db262016-04-29 00:57:13 -07002558 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2559 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2560 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002561}
2562
solenberg2100c0b2017-03-01 11:29:29 -08002563// Test that receiving on an unsignaled stream works (a stream is created).
2564TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002565 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002566 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002567
solenberg7e63ef02015-11-20 00:19:43 -08002568 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002569
Mirko Bonadeif859e552018-05-30 15:31:29 +02002570 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002571 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2572 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002573}
2574
Seth Hampson5897a6e2018-04-03 11:16:33 -07002575// Tests that when we add a stream without SSRCs, but contains a stream_id
2576// that it is stored and its stream id is later used when the first packet
2577// arrives to properly create a receive stream with a sync label.
2578TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2579 const char kSyncLabel[] = "sync_label";
2580 EXPECT_TRUE(SetupChannel());
2581 cricket::StreamParams unsignaled_stream;
2582 unsignaled_stream.set_stream_ids({kSyncLabel});
2583 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2584 // The stream shouldn't have been created at this point because it doesn't
2585 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002586 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002587
2588 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2589
Mirko Bonadeif859e552018-05-30 15:31:29 +02002590 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002591 EXPECT_TRUE(
2592 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2593 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2594
2595 // Removing the unsignaled stream clears the cached parameters. If a new
2596 // default unsignaled receive stream is created it will not have a sync group.
2597 channel_->RemoveRecvStream(0);
2598 channel_->RemoveRecvStream(kSsrc1);
2599
2600 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2601
Mirko Bonadeif859e552018-05-30 15:31:29 +02002602 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002603 EXPECT_TRUE(
2604 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2605 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2606}
2607
solenberg2100c0b2017-03-01 11:29:29 -08002608// Test that receiving N unsignaled stream works (streams will be created), and
2609// that packets are forwarded to them all.
2610TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002611 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002612 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002613 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2614
solenberg2100c0b2017-03-01 11:29:29 -08002615 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002616 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002617 rtc::SetBE32(&packet[8], ssrc);
2618 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002619
solenberg2100c0b2017-03-01 11:29:29 -08002620 // Verify we have one new stream for each loop iteration.
2621 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002622 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2623 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002624 }
mflodman3d7db262016-04-29 00:57:13 -07002625
solenberg2100c0b2017-03-01 11:29:29 -08002626 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002627 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002628 rtc::SetBE32(&packet[8], ssrc);
2629 DeliverPacket(packet, sizeof(packet));
2630
solenbergebb349d2017-03-13 05:46:15 -07002631 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002632 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2633 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2634 }
2635
2636 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2637 constexpr uint32_t kAnotherSsrc = 667;
2638 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002639 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002640
2641 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002642 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002643 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002644 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002645 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2646 EXPECT_EQ(2, streams[i]->received_packets());
2647 }
2648 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2649 EXPECT_EQ(1, streams[i]->received_packets());
2650 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002651 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002652}
2653
solenberg2100c0b2017-03-01 11:29:29 -08002654// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002655// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002656TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002657 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002658 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002659 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2660
2661 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002662 const uint32_t signaled_ssrc = 1;
2663 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002664 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002665 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002666 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2667 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002668 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002669
2670 // Note that the first unknown SSRC cannot be 0, because we only support
2671 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002672 const uint32_t unsignaled_ssrc = 7011;
2673 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002674 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002675 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2676 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002677 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002678
2679 DeliverPacket(packet, sizeof(packet));
2680 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2681
2682 rtc::SetBE32(&packet[8], signaled_ssrc);
2683 DeliverPacket(packet, sizeof(packet));
2684 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002685 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002686}
2687
solenberg4904fb62017-02-17 12:01:14 -08002688// Two tests to verify that adding a receive stream with the same SSRC as a
2689// previously added unsignaled stream will only recreate underlying stream
2690// objects if the stream parameters have changed.
2691TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2692 EXPECT_TRUE(SetupChannel());
2693
2694 // Spawn unsignaled stream with SSRC=1.
2695 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002696 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002697 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2698 sizeof(kPcmuFrame)));
2699
2700 // Verify that the underlying stream object in Call is not recreated when a
2701 // stream with SSRC=1 is added.
2702 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002703 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002704 int audio_receive_stream_id = streams.front()->id();
2705 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002706 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002707 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2708}
2709
2710TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2711 EXPECT_TRUE(SetupChannel());
2712
2713 // Spawn unsignaled stream with SSRC=1.
2714 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002715 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002716 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2717 sizeof(kPcmuFrame)));
2718
2719 // Verify that the underlying stream object in Call *is* recreated when a
2720 // stream with SSRC=1 is added, and which has changed stream parameters.
2721 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002723 int audio_receive_stream_id = streams.front()->id();
2724 cricket::StreamParams stream_params;
2725 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002726 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002727 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002728 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002729 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2730}
2731
solenberg1ac56142015-10-13 03:58:19 -07002732// Test that AddRecvStream creates new stream.
2733TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002734 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002735 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002736}
2737
2738// Test that after adding a recv stream, we do not decode more codecs than
2739// those previously passed into SetRecvCodecs.
2740TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002741 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002742 cricket::AudioRecvParameters parameters;
2743 parameters.codecs.push_back(kIsacCodec);
2744 parameters.codecs.push_back(kPcmuCodec);
2745 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002746 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002747 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2748 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2749 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002750}
2751
2752// Test that we properly clean up any streams that were added, even if
2753// not explicitly removed.
2754TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002755 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002757 EXPECT_TRUE(AddRecvStream(1));
2758 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002759
Mirko Bonadeif859e552018-05-30 15:31:29 +02002760 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2761 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762 delete channel_;
2763 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002764 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2765 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766}
2767
wu@webrtc.org78187522013-10-07 23:32:02 +00002768TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002769 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002770 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002771}
2772
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002773TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002774 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002775 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002776 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002777}
2778
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002779// Test the InsertDtmf on default send stream as caller.
2780TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002781 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002782}
2783
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002784// Test the InsertDtmf on default send stream as callee
2785TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002786 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002787}
2788
2789// Test the InsertDtmf on specified send stream as caller.
2790TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002791 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002792}
2793
2794// Test the InsertDtmf on specified send stream as callee.
2795TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002796 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797}
2798
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002800 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002801 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002802 EXPECT_CALL(adm_,
2803 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2804 EXPECT_CALL(adm_,
2805 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2806 EXPECT_CALL(adm_,
2807 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002808
Mirko Bonadeif859e552018-05-30 15:31:29 +02002809 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002810 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811
solenberg246b8172015-12-08 09:50:23 -08002812 // Nothing set in AudioOptions, so everything should be as default.
2813 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002814 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002815 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002816 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002817 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818
2819 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002820 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2821 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002822 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002823 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824
2825 // Turn echo cancellation back on, with settings, and make sure
2826 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002827 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2828 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002829 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002830 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002832 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2833 // control.
solenberg76377c52017-02-21 00:54:31 -08002834 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2835 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002836 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002837 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002838
2839 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002840 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2841 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002842 send_parameters_.options.delay_agnostic_aec = false;
2843 send_parameters_.options.extended_filter_aec = false;
2844 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002845 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002846
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002847 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002848 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2849 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002850 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002851 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002852
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002854 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2855 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002856 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002857 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002858 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002859 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860
2861 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002862 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2863 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002864 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002865 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002866 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002867 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002869 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002870 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002872 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002874 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002875 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002877 send_parameters_.options.noise_suppression = false;
2878 send_parameters_.options.highpass_filter = false;
2879 send_parameters_.options.typing_detection = false;
2880 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002881 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002882 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883
solenberg1ac56142015-10-13 03:58:19 -07002884 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002889 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002892 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893}
2894
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002896 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002897 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002898 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002899 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002900 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002901 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002902 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002903 EXPECT_CALL(adm_,
2904 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2905 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2906 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002907 webrtc::AudioProcessing::Config apm_config;
2908 EXPECT_CALL(*apm_, GetConfig())
2909 .Times(10)
2910 .WillRepeatedly(ReturnPointee(&apm_config));
2911 EXPECT_CALL(*apm_, ApplyConfig(_))
2912 .Times(10)
2913 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002914 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002915
kwiberg686a8ef2016-02-26 03:00:35 -08002916 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002917 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002918 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002919 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002920 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002921 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922
2923 // Have to add a stream to make SetSend work.
2924 cricket::StreamParams stream1;
2925 stream1.ssrcs.push_back(1);
2926 channel1->AddSendStream(stream1);
2927 cricket::StreamParams stream2;
2928 stream2.ssrcs.push_back(2);
2929 channel2->AddSendStream(stream2);
2930
2931 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002933 parameters_options_all.options.echo_cancellation = true;
2934 parameters_options_all.options.auto_gain_control = true;
2935 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002936 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2937 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002938 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002939 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002940 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002941 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002942 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002943 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002944 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946
2947 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002948 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002949 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002950 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2951 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002952 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002953 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002954 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002955 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002956 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002957 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002958 expected_options.echo_cancellation = true;
2959 expected_options.auto_gain_control = true;
2960 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002961 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962
2963 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002964 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002965 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002966 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2967 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002968 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002969 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002970 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002972 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002973 expected_options.echo_cancellation = true;
2974 expected_options.auto_gain_control = false;
2975 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002976 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977
solenberg76377c52017-02-21 00:54:31 -08002978 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2979 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002980 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002981 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002982 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002983 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002984 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985
solenberg76377c52017-02-21 00:54:31 -08002986 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2987 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002988 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002989 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002990 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002991 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002992 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
solenberg76377c52017-02-21 00:54:31 -08002994 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2995 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002996 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002997 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002998 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002999 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003000 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003002 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003003 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3004 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003005 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3006 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08003007 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3008 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003009 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003010 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003011 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003012 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003013 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01003014 expected_options.echo_cancellation = true;
3015 expected_options.auto_gain_control = false;
3016 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003017 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018}
3019
wu@webrtc.orgde305012013-10-31 15:40:38 +00003020// This test verifies DSCP settings are properly applied on voice media channel.
3021TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003022 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003023 cricket::FakeNetworkInterface network_interface;
3024 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003025 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003026
peahb1c9d1d2017-07-25 15:45:24 -07003027 webrtc::AudioProcessing::Config apm_config;
3028 EXPECT_CALL(*apm_, GetConfig())
3029 .Times(3)
3030 .WillRepeatedly(ReturnPointee(&apm_config));
3031 EXPECT_CALL(*apm_, ApplyConfig(_))
3032 .Times(3)
3033 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003034 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003035
solenbergbc37fc82016-04-04 09:54:44 -07003036 channel.reset(
3037 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003038 channel->SetInterface(&network_interface);
3039 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3040 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3041
3042 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003043 channel.reset(
3044 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003045 channel->SetInterface(&network_interface);
3046 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3047
3048 // Verify that setting the option to false resets the
3049 // DiffServCodePoint.
3050 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003051 channel.reset(
3052 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003053 channel->SetInterface(&network_interface);
3054 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3055 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3056
3057 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003058}
3059
solenberg4bac9c52015-10-09 02:32:53 -07003060TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003061 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003062 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003064 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003065 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003066 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3067 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3068 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003069}
3070
solenberg2100c0b2017-03-01 11:29:29 -08003071TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003072 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003073
3074 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003075 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003076 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3077
3078 // Should remember the volume "2" which will be set on new unsignaled streams,
3079 // and also set the gain to 2 on existing unsignaled streams.
3080 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3081 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3082
3083 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3084 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3085 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3086 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3087 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3088 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3089
3090 // Setting gain with SSRC=0 should affect all unsignaled streams.
3091 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003092 if (kMaxUnsignaledRecvStreams > 1) {
3093 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3094 }
solenberg2100c0b2017-03-01 11:29:29 -08003095 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3096
3097 // Setting gain on an individual stream affects only that.
3098 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003099 if (kMaxUnsignaledRecvStreams > 1) {
3100 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3101 }
solenberg2100c0b2017-03-01 11:29:29 -08003102 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003103}
3104
Seth Hampson845e8782018-03-02 11:34:10 -08003105TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003106 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003107 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003108
solenbergff976312016-03-30 23:28:51 -07003109 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003110 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003111 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003112 // Creating two channels to make sure that sync label is set properly for both
3113 // the default voice channel and following ones.
3114 EXPECT_TRUE(channel_->AddRecvStream(sp));
3115 sp.ssrcs[0] += 1;
3116 EXPECT_TRUE(channel_->AddRecvStream(sp));
3117
Mirko Bonadeif859e552018-05-30 15:31:29 +02003118 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003119 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003120 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003121 << "SyncGroup should be set based on stream id";
3122 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003123 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003124 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003125}
3126
solenberg3a941542015-11-16 07:34:50 -08003127// TODO(solenberg): Remove, once recv streams are configured through Call.
3128// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003129TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 // Test that setting the header extensions results in the expected state
3131 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003132 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003133 ssrcs.push_back(223);
3134 ssrcs.push_back(224);
3135
solenbergff976312016-03-30 23:28:51 -07003136 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003137 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003138 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003139 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003140 cricket::StreamParams::CreateLegacy(ssrc)));
3141 }
3142
Mirko Bonadeif859e552018-05-30 15:31:29 +02003143 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003144 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003145 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003147 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003148 }
3149
3150 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003151 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003152 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003153 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003154 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003155 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003156 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003157 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003158 EXPECT_NE(nullptr, s);
3159 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003160 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3161 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003162 for (const auto& s_ext : s_exts) {
3163 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003164 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003165 }
3166 }
3167 }
3168 }
3169
3170 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003171 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003172 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003173 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003174 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003175 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003176 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003177}
3178
3179TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3180 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003181 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003182 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003183 static const unsigned char kRtcp[] = {
3184 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3185 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3188 };
jbaucheec21bd2016-03-20 06:15:43 -07003189 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003190
solenbergff976312016-03-30 23:28:51 -07003191 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003192 cricket::WebRtcVoiceMediaChannel* media_channel =
3193 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003194 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003195 EXPECT_TRUE(media_channel->AddRecvStream(
3196 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3197
Mirko Bonadeif859e552018-05-30 15:31:29 +02003198 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003199 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003200 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003201 EXPECT_EQ(0, s->received_packets());
3202 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3203 EXPECT_EQ(1, s->received_packets());
3204 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3205 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003206}
Minyue2013aec2015-05-13 14:14:42 +02003207
solenberg0a617e22015-10-20 15:49:38 -07003208// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003209// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003210TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003211 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003212 EXPECT_TRUE(AddRecvStream(kSsrcY));
3213 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003214 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003215 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3216 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3217 EXPECT_TRUE(AddRecvStream(kSsrcW));
3218 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003219}
3220
solenberg7602aab2016-11-14 11:30:07 -08003221TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3222 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003223 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003224 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003225 cricket::StreamParams::CreateLegacy(kSsrcY)));
3226 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3227 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3228 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003229 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003230 cricket::StreamParams::CreateLegacy(kSsrcW)));
3231 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3232 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003233}
stefan658910c2015-09-03 05:48:32 -07003234
deadbeef884f5852016-01-15 09:20:04 -08003235TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003236 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003237 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3238 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003239
3240 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003241 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3242 EXPECT_TRUE(AddRecvStream(kSsrcX));
3243 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003244
3245 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003246 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3247 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003248
3249 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003250 channel_->SetRawAudioSink(kSsrcX, nullptr);
3251 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003252}
3253
solenberg2100c0b2017-03-01 11:29:29 -08003254TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003255 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003256 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3257 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003258 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3259 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003260
3261 // Should be able to set a default sink even when no stream exists.
3262 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3263
solenberg2100c0b2017-03-01 11:29:29 -08003264 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3265 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003266 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003267 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003268
3269 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003270 channel_->SetRawAudioSink(kSsrc0, nullptr);
3271 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003272
3273 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003274 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3275 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003276
3277 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003279 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003280 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3281
3282 // Spawn another unsignaled stream - it should be assigned the default sink
3283 // and the previous unsignaled stream should lose it.
3284 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3285 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3286 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3287 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003288 if (kMaxUnsignaledRecvStreams > 1) {
3289 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3290 }
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3292
3293 // Reset the default sink - the second unsignaled stream should lose it.
3294 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003295 if (kMaxUnsignaledRecvStreams > 1) {
3296 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3297 }
solenberg2100c0b2017-03-01 11:29:29 -08003298 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3299
3300 // Try setting the default sink while two streams exists.
3301 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003302 if (kMaxUnsignaledRecvStreams > 1) {
3303 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3304 }
solenberg2100c0b2017-03-01 11:29:29 -08003305 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3306
3307 // Try setting the sink for the first unsignaled stream using its known SSRC.
3308 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003309 if (kMaxUnsignaledRecvStreams > 1) {
3310 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3311 }
solenberg2100c0b2017-03-01 11:29:29 -08003312 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003313 if (kMaxUnsignaledRecvStreams > 1) {
3314 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3315 }
deadbeef884f5852016-01-15 09:20:04 -08003316}
3317
skvlad7a43d252016-03-22 15:32:27 -07003318// Test that, just like the video channel, the voice channel communicates the
3319// network state to the call.
3320TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003321 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003322
3323 EXPECT_EQ(webrtc::kNetworkUp,
3324 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3325 EXPECT_EQ(webrtc::kNetworkUp,
3326 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3327
3328 channel_->OnReadyToSend(false);
3329 EXPECT_EQ(webrtc::kNetworkDown,
3330 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3331 EXPECT_EQ(webrtc::kNetworkUp,
3332 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3333
3334 channel_->OnReadyToSend(true);
3335 EXPECT_EQ(webrtc::kNetworkUp,
3336 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3337 EXPECT_EQ(webrtc::kNetworkUp,
3338 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3339}
3340
aleloi18e0b672016-10-04 02:45:47 -07003341// Test that playout is still started after changing parameters
3342TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3343 SetupRecvStream();
3344 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003345 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003346
3347 // Changing RTP header extensions will recreate the AudioReceiveStream.
3348 cricket::AudioRecvParameters parameters;
3349 parameters.extensions.push_back(
3350 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3351 channel_->SetRecvParameters(parameters);
3352
solenberg2100c0b2017-03-01 11:29:29 -08003353 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003354}
3355
Zhi Huangfa266ef2017-12-13 10:27:46 -08003356// Tests when GetSources is called with non-existing ssrc, it will return an
3357// empty list of RtpSource without crashing.
3358TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3359 // Setup an recv stream with |kSsrcX|.
3360 SetupRecvStream();
3361 cricket::WebRtcVoiceMediaChannel* media_channel =
3362 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3363 // Call GetSources with |kSsrcY| which doesn't exist.
3364 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3365 EXPECT_EQ(0u, sources.size());
3366}
3367
stefan658910c2015-09-03 05:48:32 -07003368// Tests that the library initializes and shuts down properly.
3369TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003370 // If the VoiceEngine wants to gather available codecs early, that's fine but
3371 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003372 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003373 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003374 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003375 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003376 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003377 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003378 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003379 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003380 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003381 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003382 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3383 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003384 EXPECT_TRUE(channel != nullptr);
3385 delete channel;
solenbergff976312016-03-30 23:28:51 -07003386}
stefan658910c2015-09-03 05:48:32 -07003387
solenbergff976312016-03-30 23:28:51 -07003388// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003389TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3390 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003391 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003392 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003393 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003394 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003395 {
peaha9cc40b2017-06-29 08:32:09 -07003396 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003397 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003398 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003399 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003400 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003401 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003402 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003403 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003404 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003405 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3406 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3407 EXPECT_TRUE(channel != nullptr);
3408 delete channel;
3409 }
stefan658910c2015-09-03 05:48:32 -07003410}
3411
ossu20a4b3f2017-04-27 02:08:52 -07003412// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3413TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003414 // TODO(ossu): Why are the payload types of codecs with non-static payload
3415 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003416 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003417 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003418 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003419 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003420 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003421 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003422 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003423 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003424 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3425 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3426 (clockrate == 0 || codec.clockrate == clockrate);
3427 };
3428 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003429 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003430 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003431 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003432 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003433 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003434 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003435 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003436 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003437 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003438 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003439 EXPECT_EQ(126, codec.id);
3440 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3441 // Remove these checks once both send and receive side assigns payload types
3442 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003443 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003444 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003445 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003446 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003447 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003448 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003449 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003450 EXPECT_EQ(111, codec.id);
3451 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3452 EXPECT_EQ("10", codec.params.find("minptime")->second);
3453 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3454 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003455 }
3456 }
stefan658910c2015-09-03 05:48:32 -07003457}
3458
3459// Tests that VoE supports at least 32 channels
3460TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003461 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003462 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003463 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003464 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003465 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003466 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003467 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003468 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003469 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003470 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003471
3472 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003473 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003474 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003475 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3476 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003477 if (!channel)
3478 break;
stefan658910c2015-09-03 05:48:32 -07003479 channels[num_channels++] = channel;
3480 }
3481
Mirko Bonadeif859e552018-05-30 15:31:29 +02003482 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003483 EXPECT_EQ(expected, num_channels);
3484
3485 while (num_channels > 0) {
3486 delete channels[--num_channels];
3487 }
stefan658910c2015-09-03 05:48:32 -07003488}
3489
3490// Test that we set our preferred codecs properly.
3491TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003492 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3493 // - Check that our builtin codecs are usable by Channel.
3494 // - The codecs provided by the engine is usable by Channel.
3495 // It does not check that the codecs in the RecvParameters are actually
3496 // what we sent in - though it's probably reasonable to expect so, if
3497 // SetRecvParameters returns true.
3498 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003499 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003500 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003501 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003502 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003503 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003504 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003505 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003506 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003507 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003508 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003509 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3510 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003511 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003512 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003513 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003514}
ossu9def8002017-02-09 05:14:32 -08003515
3516TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3517 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003518 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3519 {48000, 2, 16000, 10000, 20000}};
3520 spec1.info.allow_comfort_noise = false;
3521 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003522 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003523 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3524 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003525 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003526 specs.push_back(webrtc::AudioCodecSpec{
3527 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3528 {16000, 1, 13300}});
3529 specs.push_back(
3530 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3531 specs.push_back(
3532 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003533
ossueb1fde42017-05-02 06:46:30 -07003534 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3535 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3536 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003537 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003538 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003539 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003540 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003541
peaha9cc40b2017-06-29 08:32:09 -07003542 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003543 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003544 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003545 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003546 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003547 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003548 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003549
3550 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3551 // check the actual values safely, to provide better test results.
3552 auto get_codec =
3553 [&codecs](size_t index) -> const cricket::AudioCodec& {
3554 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3555 if (codecs.size() > index)
3556 return codecs[index];
3557 return missing_codec;
3558 };
3559
3560 // Ensure the general codecs are generated first and in order.
3561 for (size_t i = 0; i != specs.size(); ++i) {
3562 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3563 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3564 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3565 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3566 }
3567
3568 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003569 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003570 auto find_codec =
3571 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3572 for (size_t i = 0; i != codecs.size(); ++i) {
3573 const cricket::AudioCodec& codec = codecs[i];
3574 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3575 codec.clockrate == format.clockrate_hz &&
3576 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003577 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003578 }
3579 }
3580 return -1;
3581 };
3582
3583 // Ensure all supplementary codecs are generated last. Their internal ordering
3584 // is not important.
3585 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3586 const int num_specs = static_cast<int>(specs.size());
3587 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3588 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3589 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3590 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3591 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3592 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3593 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3594}