blob: d71d77d8a8aedb5ce3d430b64b2096fa238d517f [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() {
220 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000221 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800224 return false;
225 }
peaha9cc40b2017-06-29 08:32:09 -0700226 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800227 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 }
solenberg8189b022016-06-14 12:13:00 -0700229
230 bool AddRecvStream(uint32_t ssrc) {
231 EXPECT_TRUE(channel_);
232 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
233 }
234
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000235 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700236 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700237 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800238 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
239 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700240 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800241 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000242 }
solenberg8189b022016-06-14 12:13:00 -0700243
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700245 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 }
solenberg8189b022016-06-14 12:13:00 -0700248
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200249 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 }
252
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100253 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
254 const auto* send_stream = call_.GetAudioSendStream(ssrc);
255 EXPECT_TRUE(send_stream);
256 return *send_stream;
257 }
258
deadbeef884f5852016-01-15 09:20:04 -0800259 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
260 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
261 EXPECT_TRUE(recv_stream);
262 return *recv_stream;
263 }
264
solenberg3a941542015-11-16 07:34:50 -0800265 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800266 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800267 }
268
solenberg7add0582015-11-20 09:59:34 -0800269 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800270 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800271 }
272
solenberg059fb442016-10-26 05:12:24 -0700273 void SetSend(bool enable) {
274 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700275 if (enable) {
276 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
277 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
278 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700279 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700280 }
solenberg059fb442016-10-26 05:12:24 -0700281 channel_->SetSend(enable);
282 }
283
284 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700285 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700286 ASSERT_TRUE(channel_);
287 EXPECT_TRUE(channel_->SetSendParameters(params));
288 }
289
minyue6b825df2016-10-31 04:08:32 -0700290 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
291 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700292 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700293 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700294 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700295 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700296 }
297 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700298 }
299
solenbergffbbcac2016-11-17 05:25:37 -0800300 void TestInsertDtmf(uint32_t ssrc, bool caller,
301 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700302 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000303 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700304 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000305 // send stream.
306 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800307 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000308 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000309
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700311 SetSendParameters(send_parameters_);
312 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800314 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800315 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700316 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318
319 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700320 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800323 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000324 }
325
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800327 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100329 // Test send.
330 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800331 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100332 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800334 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800335 EXPECT_EQ(codec.id, telephone_event.payload_type);
336 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100337 EXPECT_EQ(2, telephone_event.event_code);
338 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 }
340
341 // Test that send bandwidth is set correctly.
342 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000343 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
344 // |expected_result| is the expected result from SetMaxSendBandwidth().
345 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700346 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
347 int max_bitrate,
348 bool expected_result,
349 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200350 cricket::AudioSendParameters parameters;
351 parameters.codecs.push_back(codec);
352 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700353 if (expected_result) {
354 SetSendParameters(parameters);
355 } else {
356 EXPECT_FALSE(channel_->SetSendParameters(parameters));
357 }
solenberg2100c0b2017-03-01 11:29:29 -0800358 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 }
360
skvlade0d46372016-04-07 22:59:22 -0700361 // Sets the per-stream maximum bitrate limit for the specified SSRC.
362 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700363 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700364 EXPECT_EQ(1UL, parameters.encodings.size());
365
Oskar Sundbom78807582017-11-16 11:09:55 +0100366 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800367 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700368 }
369
solenberg059fb442016-10-26 05:12:24 -0700370 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700371 cricket::AudioSendParameters send_parameters;
372 send_parameters.codecs.push_back(codec);
373 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700374 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700375 }
376
ossu20a4b3f2017-04-27 02:08:52 -0700377 void CheckSendCodecBitrate(int32_t ssrc,
378 const char expected_name[],
379 int expected_bitrate) {
380 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
381 EXPECT_EQ(expected_name, spec->format.name);
382 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700383 }
384
ossu20a4b3f2017-04-27 02:08:52 -0700385 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
386 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700387 }
388
minyue6b825df2016-10-31 04:08:32 -0700389 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
390 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
391 }
392
skvlade0d46372016-04-07 22:59:22 -0700393 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
394 int global_max,
395 int stream_max,
396 bool expected_result,
397 int expected_codec_bitrate) {
398 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800399 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700400
401 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700402 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800403 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700404
405 // Verify that reading back the parameters gives results
406 // consistent with the Set() result.
407 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800408 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700409 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
410 EXPECT_EQ(expected_result ? stream_max : -1,
411 resulting_parameters.encodings[0].max_bitrate_bps);
412
413 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800414 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700415 }
416
stefan13f1a0a2016-11-30 07:22:58 -0800417 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
418 int expected_min_bitrate_bps,
419 const char* start_bitrate_kbps,
420 int expected_start_bitrate_bps,
421 const char* max_bitrate_kbps,
422 int expected_max_bitrate_bps) {
423 EXPECT_TRUE(SetupSendStream());
424 auto& codecs = send_parameters_.codecs;
425 codecs.clear();
426 codecs.push_back(kOpusCodec);
427 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
428 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
429 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100430 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
431 SetSdpBitrateParameters(
432 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
433 expected_min_bitrate_bps),
434 Field(&BitrateConstraints::start_bitrate_bps,
435 expected_start_bitrate_bps),
436 Field(&BitrateConstraints::max_bitrate_bps,
437 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800438
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100439 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800440 }
441
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000442 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700443 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000444
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000445 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800446 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000447
448 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700449 send_parameters_.extensions.push_back(
450 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700451 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800452 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000453
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000454 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200455 send_parameters_.extensions.clear();
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
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000459 // Ensure extension is set properly.
460 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700461 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700462 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800463 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
464 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
465 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000466
solenberg7add0582015-11-20 09:59:34 -0800467 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000468 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800469 cricket::StreamParams::CreateLegacy(kSsrcY)));
470 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
471 call_.GetAudioSendStream(kSsrcY));
472 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
473 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
474 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000475
476 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200477 send_parameters_.codecs.push_back(kPcmuCodec);
478 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700479 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800480 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
481 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482 }
483
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000484 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700485 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800488 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489
490 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700491 recv_parameters_.extensions.push_back(
492 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800493 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000495
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000496 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800497 recv_parameters_.extensions.clear();
498 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 extension is set properly.
502 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700503 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800504 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800505 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
506 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
507 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000508
solenberg7add0582015-11-20 09:59:34 -0800509 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_TRUE(AddRecvStream(kSsrcY));
511 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
512 call_.GetAudioReceiveStream(kSsrcY));
513 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
514 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
515 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000516
517 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800518 recv_parameters_.extensions.clear();
519 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
521 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000522 }
523
solenberg85a04962015-10-27 03:35:21 -0700524 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
525 webrtc::AudioSendStream::Stats stats;
526 stats.local_ssrc = 12;
527 stats.bytes_sent = 345;
528 stats.packets_sent = 678;
529 stats.packets_lost = 9012;
530 stats.fraction_lost = 34.56f;
531 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100532 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700533 stats.ext_seqnum = 789;
534 stats.jitter_ms = 12;
535 stats.rtt_ms = 345;
536 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100537 stats.apm_statistics.delay_median_ms = 234;
538 stats.apm_statistics.delay_standard_deviation_ms = 567;
539 stats.apm_statistics.echo_return_loss = 890;
540 stats.apm_statistics.echo_return_loss_enhancement = 1234;
541 stats.apm_statistics.residual_echo_likelihood = 0.432f;
542 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100543 stats.ana_statistics.bitrate_action_counter = 321;
544 stats.ana_statistics.channel_action_counter = 432;
545 stats.ana_statistics.dtx_action_counter = 543;
546 stats.ana_statistics.fec_action_counter = 654;
547 stats.ana_statistics.frame_length_increase_counter = 765;
548 stats.ana_statistics.frame_length_decrease_counter = 876;
549 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700550 stats.typing_noise_detected = true;
551 return stats;
552 }
553 void SetAudioSendStreamStats() {
554 for (auto* s : call_.GetAudioSendStreams()) {
555 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200556 }
solenberg85a04962015-10-27 03:35:21 -0700557 }
solenberg566ef242015-11-06 15:34:49 -0800558 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
559 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700560 const auto stats = GetAudioSendStreamStats();
561 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
562 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
563 EXPECT_EQ(info.packets_sent, stats.packets_sent);
564 EXPECT_EQ(info.packets_lost, stats.packets_lost);
565 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
566 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800567 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700568 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
569 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
570 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
571 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100572 EXPECT_EQ(info.apm_statistics.delay_median_ms,
573 stats.apm_statistics.delay_median_ms);
574 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
575 stats.apm_statistics.delay_standard_deviation_ms);
576 EXPECT_EQ(info.apm_statistics.echo_return_loss,
577 stats.apm_statistics.echo_return_loss);
578 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
579 stats.apm_statistics.echo_return_loss_enhancement);
580 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
581 stats.apm_statistics.residual_echo_likelihood);
582 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
583 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700584 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
585 stats.ana_statistics.bitrate_action_counter);
586 EXPECT_EQ(info.ana_statistics.channel_action_counter,
587 stats.ana_statistics.channel_action_counter);
588 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
589 stats.ana_statistics.dtx_action_counter);
590 EXPECT_EQ(info.ana_statistics.fec_action_counter,
591 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700592 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
593 stats.ana_statistics.frame_length_increase_counter);
594 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
595 stats.ana_statistics.frame_length_decrease_counter);
596 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
597 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800598 EXPECT_EQ(info.typing_noise_detected,
599 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700600 }
601
602 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
603 webrtc::AudioReceiveStream::Stats stats;
604 stats.remote_ssrc = 123;
605 stats.bytes_rcvd = 456;
606 stats.packets_rcvd = 768;
607 stats.packets_lost = 101;
608 stats.fraction_lost = 23.45f;
609 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100610 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700611 stats.ext_seqnum = 678;
612 stats.jitter_ms = 901;
613 stats.jitter_buffer_ms = 234;
614 stats.jitter_buffer_preferred_ms = 567;
615 stats.delay_estimate_ms = 890;
616 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700617 stats.total_samples_received = 5678901;
618 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200619 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200620 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700621 stats.expand_rate = 5.67f;
622 stats.speech_expand_rate = 8.90f;
623 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200624 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700625 stats.accelerate_rate = 4.56f;
626 stats.preemptive_expand_rate = 7.89f;
627 stats.decoding_calls_to_silence_generator = 12;
628 stats.decoding_calls_to_neteq = 345;
629 stats.decoding_normal = 67890;
630 stats.decoding_plc = 1234;
631 stats.decoding_cng = 5678;
632 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700633 stats.decoding_muted_output = 3456;
634 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200635 return stats;
636 }
637 void SetAudioReceiveStreamStats() {
638 for (auto* s : call_.GetAudioReceiveStreams()) {
639 s->SetStats(GetAudioReceiveStreamStats());
640 }
641 }
642 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700643 const auto stats = GetAudioReceiveStreamStats();
644 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
645 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
646 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
647 EXPECT_EQ(info.packets_lost, stats.packets_lost);
648 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
649 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800650 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700651 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
652 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
653 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200654 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700655 stats.jitter_buffer_preferred_ms);
656 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
657 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700658 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
659 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200660 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200661 EXPECT_EQ(info.jitter_buffer_delay_seconds,
662 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700663 EXPECT_EQ(info.expand_rate, stats.expand_rate);
664 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
665 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200666 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700667 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
668 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200669 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700670 stats.decoding_calls_to_silence_generator);
671 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
672 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
673 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
674 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
675 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700676 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700677 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200678 }
hbos1acfbd22016-11-17 23:43:29 -0800679 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
680 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
681 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
682 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
683 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
684 codec.ToCodecParameters());
685 }
686 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
687 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
688 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
689 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
690 codec.ToCodecParameters());
691 }
692 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200693
peah8271d042016-11-22 07:24:52 -0800694 bool IsHighPassFilterEnabled() {
695 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
696 }
697
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700699 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700700 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800701 webrtc::test::MockGainControl& apm_gc_;
702 webrtc::test::MockEchoCancellation& apm_ec_;
703 webrtc::test::MockNoiseSuppression& apm_ns_;
704 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200705 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700706 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700707 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200708 cricket::AudioSendParameters send_parameters_;
709 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800710 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700711 webrtc::AudioProcessing::Config apm_config_;
712
stefanba4c0e42016-02-04 04:12:24 -0800713 private:
714 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715};
716
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717// Tests that we can create and destroy a channel.
718TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700719 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720}
721
solenberg31fec402016-05-06 02:13:12 -0700722// Test that we can add a send stream and that it has the correct defaults.
723TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
724 EXPECT_TRUE(SetupChannel());
725 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800726 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
727 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
728 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700729 EXPECT_EQ("", config.rtp.c_name);
730 EXPECT_EQ(0u, config.rtp.extensions.size());
731 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
732 config.send_transport);
733}
734
735// Test that we can add a receive stream and that it has the correct defaults.
736TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
737 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800738 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700739 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800740 GetRecvStreamConfig(kSsrcX);
741 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700742 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
743 EXPECT_FALSE(config.rtp.transport_cc);
744 EXPECT_EQ(0u, config.rtp.extensions.size());
745 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
746 config.rtcp_send_transport);
747 EXPECT_EQ("", config.sync_group);
748}
749
stefanba4c0e42016-02-04 04:12:24 -0800750TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700751 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800752 bool opus_found = false;
753 for (cricket::AudioCodec codec : codecs) {
754 if (codec.name == "opus") {
755 EXPECT_TRUE(HasTransportCc(codec));
756 opus_found = true;
757 }
758 }
759 EXPECT_TRUE(opus_found);
760}
761
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762// Test that we set our inbound codecs properly, including changing PT.
763TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700764 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200765 cricket::AudioRecvParameters parameters;
766 parameters.codecs.push_back(kIsacCodec);
767 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800768 parameters.codecs.push_back(kTelephoneEventCodec1);
769 parameters.codecs.push_back(kTelephoneEventCodec2);
770 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200771 parameters.codecs[2].id = 126;
772 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800773 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700774 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
775 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
776 {{0, {"PCMU", 8000, 1}},
777 {106, {"ISAC", 16000, 1}},
778 {126, {"telephone-event", 8000, 1}},
779 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780}
781
782// Test that we fail to set an unknown inbound codec.
783TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700784 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 cricket::AudioRecvParameters parameters;
786 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700787 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200788 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail if we have duplicate types in the inbound list.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
796 parameters.codecs.push_back(kCn16000Codec);
797 parameters.codecs[1].id = kIsacCodec.id;
798 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799}
800
801// Test that we can decode OPUS without stereo parameters.
802TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
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(kPcmuCodec);
807 parameters.codecs.push_back(kOpusCodec);
808 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800809 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700810 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
811 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
812 {{0, {"PCMU", 8000, 1}},
813 {103, {"ISAC", 16000, 1}},
814 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815}
816
817// Test that we can decode OPUS with stereo = 0.
818TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700819 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200820 cricket::AudioRecvParameters parameters;
821 parameters.codecs.push_back(kIsacCodec);
822 parameters.codecs.push_back(kPcmuCodec);
823 parameters.codecs.push_back(kOpusCodec);
824 parameters.codecs[2].params["stereo"] = "0";
825 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800826 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700827 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
828 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
829 {{0, {"PCMU", 8000, 1}},
830 {103, {"ISAC", 16000, 1}},
831 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832}
833
834// Test that we can decode OPUS with stereo = 1.
835TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700836 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200837 cricket::AudioRecvParameters parameters;
838 parameters.codecs.push_back(kIsacCodec);
839 parameters.codecs.push_back(kPcmuCodec);
840 parameters.codecs.push_back(kOpusCodec);
841 parameters.codecs[2].params["stereo"] = "1";
842 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800843 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700844 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
845 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
846 {{0, {"PCMU", 8000, 1}},
847 {103, {"ISAC", 16000, 1}},
848 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849}
850
851// Test that changes to recv codecs are applied to all streams.
852TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700853 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200854 cricket::AudioRecvParameters parameters;
855 parameters.codecs.push_back(kIsacCodec);
856 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800857 parameters.codecs.push_back(kTelephoneEventCodec1);
858 parameters.codecs.push_back(kTelephoneEventCodec2);
859 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200860 parameters.codecs[2].id = 126;
861 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700862 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
863 EXPECT_TRUE(AddRecvStream(ssrc));
864 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
865 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
866 {{0, {"PCMU", 8000, 1}},
867 {106, {"ISAC", 16000, 1}},
868 {126, {"telephone-event", 8000, 1}},
869 {107, {"telephone-event", 32000, 1}}})));
870 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000871}
872
873TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700874 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200875 cricket::AudioRecvParameters parameters;
876 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800877 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000879
solenberg2100c0b2017-03-01 11:29:29 -0800880 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800881 ASSERT_EQ(1, dm.count(106));
882 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883}
884
885// Test that we can apply the same set of codecs again while playing.
886TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700887 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200888 cricket::AudioRecvParameters parameters;
889 parameters.codecs.push_back(kIsacCodec);
890 parameters.codecs.push_back(kCn16000Codec);
891 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700892 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200893 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894
deadbeefcb383672017-04-26 16:28:42 -0700895 // Remapping a payload type to a different codec should fail.
896 parameters.codecs[0] = kOpusCodec;
897 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800899 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900}
901
902// Test that we can add a codec while playing.
903TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700904 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200905 cricket::AudioRecvParameters parameters;
906 parameters.codecs.push_back(kIsacCodec);
907 parameters.codecs.push_back(kCn16000Codec);
908 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700909 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 parameters.codecs.push_back(kOpusCodec);
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800913 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914}
915
deadbeefcb383672017-04-26 16:28:42 -0700916// Test that we accept adding the same codec with a different payload type.
917// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
918TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
919 EXPECT_TRUE(SetupRecvStream());
920 cricket::AudioRecvParameters parameters;
921 parameters.codecs.push_back(kIsacCodec);
922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
923
924 ++parameters.codecs[0].id;
925 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
926}
927
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700929 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000931 // Test that when autobw is enabled, bitrate is kept as the default
932 // value. autobw is enabled for the following tests because the target
933 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
935 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700936 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
938 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700939 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
ossu20a4b3f2017-04-27 02:08:52 -0700941 // opus, default bitrate == 32000 in mono.
942 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943}
944
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000945TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700946 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700949 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
950 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700951 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700954 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
955 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
956 // Rates above the max (510000) should be capped.
957 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958}
959
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000960TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700961 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000962
963 // Test that we can only set a maximum bitrate for a fixed-rate codec
964 // if it's bigger than the fixed rate.
965
966 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700967 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
968 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
969 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
970 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
971 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
972 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
973 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000974}
975
976TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700977 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 const int kDesiredBitrate = 128000;
979 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700980 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200981 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700982 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000983
984 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800985 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000986
solenberg2100c0b2017-03-01 11:29:29 -0800987 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000988}
989
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000990// Test that bitrate cannot be set for CBR codecs.
991// Bitrate is ignored if it is higher than the fixed bitrate.
992// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000993TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700994 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995
996 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700997 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800998 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200999
1000 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001001 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001002 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001003
1004 send_parameters_.max_bandwidth_bps = 128;
1005 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001006 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007}
1008
skvlade0d46372016-04-07 22:59:22 -07001009// Test that the per-stream bitrate limit and the global
1010// bitrate limit both apply.
1011TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1012 EXPECT_TRUE(SetupSendStream());
1013
ossu20a4b3f2017-04-27 02:08:52 -07001014 // opus, default bitrate == 32000.
1015 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001016 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1017 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1018 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1019
1020 // CBR codecs allow both maximums to exceed the bitrate.
1021 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1022 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1023 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1024 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1025
1026 // CBR codecs don't allow per stream maximums to be too low.
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1029}
1030
1031// Test that an attempt to set RtpParameters for a stream that does not exist
1032// fails.
1033TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1034 EXPECT_TRUE(SetupChannel());
1035 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001036 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001037 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1038
1039 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001040 EXPECT_FALSE(
1041 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001042}
1043
1044TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001045 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001046 // This test verifies that setting RtpParameters succeeds only if
1047 // the structure contains exactly one encoding.
1048 // TODO(skvlad): Update this test when we start supporting setting parameters
1049 // for each encoding individually.
1050
1051 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001052 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001053 // Two or more encodings should result in failure.
1054 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001055 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001056 // Zero encodings should also fail.
1057 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001058 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001059}
1060
1061// Changing the SSRC through RtpParameters is not allowed.
1062TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1063 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001064 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001065 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001066 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001067}
1068
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001069// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001070// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001071TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1072 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001073 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001074 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001075 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001076 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001077 ASSERT_EQ(1u, parameters.encodings.size());
1078 ASSERT_TRUE(parameters.encodings[0].active);
1079 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001080 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001081 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082
1083 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001084 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001086 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001087 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001088 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001089}
1090
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001091// Test that SetRtpSendParameters configures the correct encoding channel for
1092// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001093TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1094 SetupForMultiSendStream();
1095 // Create send streams.
1096 for (uint32_t ssrc : kSsrcs4) {
1097 EXPECT_TRUE(
1098 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1099 }
1100 // Configure one stream to be limited by the stream config, another to be
1101 // limited by the global max, and the third one with no per-stream limit
1102 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001103 SetGlobalMaxBitrate(kOpusCodec, 32000);
1104 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1105 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001106 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1107
ossu20a4b3f2017-04-27 02:08:52 -07001108 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1109 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1110 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001111
1112 // Remove the global cap; the streams should switch to their respective
1113 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001114 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001115 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1116 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1117 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001118}
1119
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001120// Test that GetRtpSendParameters returns the currently configured codecs.
1121TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001122 EXPECT_TRUE(SetupSendStream());
1123 cricket::AudioSendParameters parameters;
1124 parameters.codecs.push_back(kIsacCodec);
1125 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001126 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001127
solenberg2100c0b2017-03-01 11:29:29 -08001128 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001130 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1131 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132}
1133
deadbeefcb443432016-12-12 11:12:36 -08001134// Test that GetRtpSendParameters returns an SSRC.
1135TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1136 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001137 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001138 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001139 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001140}
1141
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001143TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001144 EXPECT_TRUE(SetupSendStream());
1145 cricket::AudioSendParameters parameters;
1146 parameters.codecs.push_back(kIsacCodec);
1147 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001148 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149
solenberg2100c0b2017-03-01 11:29:29 -08001150 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151
1152 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001153 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001156 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1157 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158}
1159
minyuececec102017-03-27 13:04:25 -07001160// Test that max_bitrate_bps in send stream config gets updated correctly when
1161// SetRtpSendParameters is called.
1162TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1163 webrtc::test::ScopedFieldTrials override_field_trials(
1164 "WebRTC-Audio-SendSideBwe/Enabled/");
1165 EXPECT_TRUE(SetupSendStream());
1166 cricket::AudioSendParameters send_parameters;
1167 send_parameters.codecs.push_back(kOpusCodec);
1168 SetSendParameters(send_parameters);
1169
1170 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1171 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1172 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1173
1174 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001175 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001176 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001177
1178 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1179 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1180}
1181
Seth Hampson24722b32017-12-22 09:36:42 -08001182// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1183// a value <= 0, setting the parameters returns false.
1184TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1185 EXPECT_TRUE(SetupSendStream());
1186 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1187 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1188 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1189 rtp_parameters.encodings[0].bitrate_priority);
1190
1191 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001192 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001193 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001194 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001195}
1196
1197// Test that the bitrate_priority in the send stream config gets updated when
1198// SetRtpSendParameters is set for the VoiceMediaChannel.
1199TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1200 EXPECT_TRUE(SetupSendStream());
1201 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1202
1203 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1204 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1205 rtp_parameters.encodings[0].bitrate_priority);
1206 double new_bitrate_priority = 2.0;
1207 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001208 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001209
1210 // The priority should get set for both the audio channel's rtp parameters
1211 // and the audio send stream's audio config.
1212 EXPECT_EQ(
1213 new_bitrate_priority,
1214 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1215 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1216}
1217
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001218// Test that GetRtpReceiveParameters returns the currently configured codecs.
1219TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1220 EXPECT_TRUE(SetupRecvStream());
1221 cricket::AudioRecvParameters parameters;
1222 parameters.codecs.push_back(kIsacCodec);
1223 parameters.codecs.push_back(kPcmuCodec);
1224 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1225
1226 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001227 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001228 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1229 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1230 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1231}
1232
deadbeefcb443432016-12-12 11:12:36 -08001233// Test that GetRtpReceiveParameters returns an SSRC.
1234TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1235 EXPECT_TRUE(SetupRecvStream());
1236 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001237 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001238 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001239 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001240}
1241
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001242// Test that if we set/get parameters multiple times, we get the same results.
1243TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1244 EXPECT_TRUE(SetupRecvStream());
1245 cricket::AudioRecvParameters parameters;
1246 parameters.codecs.push_back(kIsacCodec);
1247 parameters.codecs.push_back(kPcmuCodec);
1248 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1249
1250 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001251 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252
1253 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001254 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001255
1256 // ... And this shouldn't change the params returned by
1257 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001258 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1259 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001260}
1261
deadbeef3bc15102017-04-20 19:25:07 -07001262// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1263// aren't signaled. It should return an empty "RtpEncodingParameters" when
1264// configured to receive an unsignaled stream and no packets have been received
1265// yet, and start returning the SSRC once a packet has been received.
1266TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1267 ASSERT_TRUE(SetupChannel());
1268 // Call necessary methods to configure receiving a default stream as
1269 // soon as it arrives.
1270 cricket::AudioRecvParameters parameters;
1271 parameters.codecs.push_back(kIsacCodec);
1272 parameters.codecs.push_back(kPcmuCodec);
1273 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1274
1275 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1276 // stream. Should return nothing.
1277 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1278
1279 // Set a sink for an unsignaled stream.
1280 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1281 // Value of "0" means "unsignaled stream".
1282 channel_->SetRawAudioSink(0, std::move(fake_sink));
1283
1284 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1285 // in this method means "unsignaled stream".
1286 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1287 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1288 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1289
1290 // Receive PCMU packet (SSRC=1).
1291 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1292
1293 // The |ssrc| member should still be unset.
1294 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1295 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1296 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1297}
1298
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001299// Test that we apply codecs properly.
1300TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001301 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001302 cricket::AudioSendParameters parameters;
1303 parameters.codecs.push_back(kIsacCodec);
1304 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001305 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001306 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001307 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001308 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001309 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1310 EXPECT_EQ(96, send_codec_spec.payload_type);
1311 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1312 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1313 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001314 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001315 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316}
1317
ossu20a4b3f2017-04-27 02:08:52 -07001318// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1319// AudioSendStream.
1320TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001321 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001322 cricket::AudioSendParameters parameters;
1323 parameters.codecs.push_back(kIsacCodec);
1324 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001325 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 parameters.codecs[0].id = 96;
1327 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001328 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001329 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001330 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001331 // Calling SetSendCodec again with same codec which is already set.
1332 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001333 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001334 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001335}
1336
ossu20a4b3f2017-04-27 02:08:52 -07001337// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1338// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001339
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001340// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001342 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001343 cricket::AudioSendParameters parameters;
1344 parameters.codecs.push_back(kOpusCodec);
1345 parameters.codecs[0].bitrate = 0;
1346 parameters.codecs[0].clockrate = 50000;
1347 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348}
1349
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001350// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001352 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001353 cricket::AudioSendParameters parameters;
1354 parameters.codecs.push_back(kOpusCodec);
1355 parameters.codecs[0].bitrate = 0;
1356 parameters.codecs[0].channels = 0;
1357 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358}
1359
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001360// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001362 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 cricket::AudioSendParameters parameters;
1364 parameters.codecs.push_back(kOpusCodec);
1365 parameters.codecs[0].bitrate = 0;
1366 parameters.codecs[0].channels = 0;
1367 parameters.codecs[0].params["stereo"] = "1";
1368 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001369}
1370
1371// Test that if channel is 1 for opus and there's no stereo, we fail.
1372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].bitrate = 0;
1377 parameters.codecs[0].channels = 1;
1378 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001379}
1380
1381// Test that if channel is 1 for opus and stereo=0, we fail.
1382TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001383 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 cricket::AudioSendParameters parameters;
1385 parameters.codecs.push_back(kOpusCodec);
1386 parameters.codecs[0].bitrate = 0;
1387 parameters.codecs[0].channels = 1;
1388 parameters.codecs[0].params["stereo"] = "0";
1389 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001390}
1391
1392// Test that if channel is 1 for opus and stereo=1, we fail.
1393TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001394 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001395 cricket::AudioSendParameters parameters;
1396 parameters.codecs.push_back(kOpusCodec);
1397 parameters.codecs[0].bitrate = 0;
1398 parameters.codecs[0].channels = 1;
1399 parameters.codecs[0].params["stereo"] = "1";
1400 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401}
1402
ossu20a4b3f2017-04-27 02:08:52 -07001403// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001405 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001406 cricket::AudioSendParameters parameters;
1407 parameters.codecs.push_back(kOpusCodec);
1408 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001409 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001410 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001411}
1412
ossu20a4b3f2017-04-27 02:08:52 -07001413// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001415 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kOpusCodec);
1418 parameters.codecs[0].bitrate = 0;
1419 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001420 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001421 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422}
1423
ossu20a4b3f2017-04-27 02:08:52 -07001424// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001425TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001426 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001427 cricket::AudioSendParameters parameters;
1428 parameters.codecs.push_back(kOpusCodec);
1429 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001430 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001434
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001436 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001437 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001438}
1439
ossu20a4b3f2017-04-27 02:08:52 -07001440// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001442 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 cricket::AudioSendParameters parameters;
1444 parameters.codecs.push_back(kOpusCodec);
1445 parameters.codecs[0].bitrate = 0;
1446 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001447 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001448 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449}
1450
ossu20a4b3f2017-04-27 02:08:52 -07001451// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001452TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001453 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 cricket::AudioSendParameters parameters;
1455 parameters.codecs.push_back(kOpusCodec);
1456 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001457 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001459 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001460 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001461
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001463 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001464 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001465}
1466
ossu20a4b3f2017-04-27 02:08:52 -07001467// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001473 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001474 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1475 EXPECT_EQ(111, spec.payload_type);
1476 EXPECT_EQ(96000, spec.target_bitrate_bps);
1477 EXPECT_EQ("opus", spec.format.name);
1478 EXPECT_EQ(2, spec.format.num_channels);
1479 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480}
1481
ossu20a4b3f2017-04-27 02:08:52 -07001482// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001483TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001484 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 cricket::AudioSendParameters parameters;
1486 parameters.codecs.push_back(kOpusCodec);
1487 parameters.codecs[0].bitrate = 30000;
1488 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001489 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001490 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491}
1492
ossu20a4b3f2017-04-27 02:08:52 -07001493// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001495 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001496 cricket::AudioSendParameters parameters;
1497 parameters.codecs.push_back(kOpusCodec);
1498 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001499 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001500 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501}
1502
ossu20a4b3f2017-04-27 02:08:52 -07001503// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001505 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001506 cricket::AudioSendParameters parameters;
1507 parameters.codecs.push_back(kOpusCodec);
1508 parameters.codecs[0].bitrate = 30000;
1509 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001510 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001511 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001512}
1513
stefan13f1a0a2016-11-30 07:22:58 -08001514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1515 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1516 200000);
1517}
1518
1519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1520 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1521}
1522
1523TEST_F(WebRtcVoiceEngineTestFake,
1524 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1525 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1526}
1527
1528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1529 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1530}
1531
1532TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001533 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001534 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1535 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001536 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001537 // Setting max bitrate should keep previous min bitrate
1538 // Setting max bitrate should not reset start bitrate.
1539 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1540 SetSdpBitrateParameters(
1541 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1542 Field(&BitrateConstraints::start_bitrate_bps, -1),
1543 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001544 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001545}
1546
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001547// Test that we can enable NACK with opus as caller.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
1552 parameters.codecs[0].AddFeedbackParam(
1553 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1554 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001557 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001558}
1559
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001560// Test that we can enable NACK with opus as callee.
1561TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001562 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001563 cricket::AudioSendParameters parameters;
1564 parameters.codecs.push_back(kOpusCodec);
1565 parameters.codecs[0].AddFeedbackParam(
1566 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1567 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001568 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001569 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001570 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001572
1573 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001574 cricket::StreamParams::CreateLegacy(kSsrcX)));
1575 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001576}
1577
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578// Test that we can enable NACK on receive streams.
1579TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001580 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001582 cricket::AudioSendParameters parameters;
1583 parameters.codecs.push_back(kOpusCodec);
1584 parameters.codecs[0].AddFeedbackParam(
1585 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1586 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001587 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1588 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1591 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
1594// Test that we can disable NACK.
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupSendStream());
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));
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001603 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001605 parameters.codecs.clear();
1606 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001607 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001608 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001609}
1610
1611// Test that we can disable NACK on receive streams.
1612TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001613 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001614 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001615 cricket::AudioSendParameters parameters;
1616 parameters.codecs.push_back(kOpusCodec);
1617 parameters.codecs[0].AddFeedbackParam(
1618 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1619 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001620 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001621 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1622 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 parameters.codecs.clear();
1625 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1628 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001629}
1630
1631// Test that NACK is enabled on a new receive stream.
1632TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001633 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001634 cricket::AudioSendParameters parameters;
1635 parameters.codecs.push_back(kIsacCodec);
1636 parameters.codecs.push_back(kCn16000Codec);
1637 parameters.codecs[0].AddFeedbackParam(
1638 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1639 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001640 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001641 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642
solenberg2100c0b2017-03-01 11:29:29 -08001643 EXPECT_TRUE(AddRecvStream(kSsrcY));
1644 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1645 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1646 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001647}
1648
stefanba4c0e42016-02-04 04:12:24 -08001649TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001650 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001651 cricket::AudioSendParameters send_parameters;
1652 send_parameters.codecs.push_back(kOpusCodec);
1653 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001655
1656 cricket::AudioRecvParameters recv_parameters;
1657 recv_parameters.codecs.push_back(kIsacCodec);
1658 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001659 EXPECT_TRUE(AddRecvStream(kSsrcX));
1660 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001661 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001662 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001663
ossudedfd282016-06-14 07:12:39 -07001664 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001666 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001667 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001668 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001669}
1670
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001671// Test that we can switch back and forth between Opus and ISAC with CN.
1672TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001673 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001674
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001675 cricket::AudioSendParameters opus_parameters;
1676 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001678 {
ossu20a4b3f2017-04-27 02:08:52 -07001679 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1680 EXPECT_EQ(111, spec.payload_type);
1681 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001682 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001684 cricket::AudioSendParameters isac_parameters;
1685 isac_parameters.codecs.push_back(kIsacCodec);
1686 isac_parameters.codecs.push_back(kCn16000Codec);
1687 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001688 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001689 {
ossu20a4b3f2017-04-27 02:08:52 -07001690 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1691 EXPECT_EQ(103, spec.payload_type);
1692 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001693 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001694
solenberg059fb442016-10-26 05:12:24 -07001695 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001696 {
ossu20a4b3f2017-04-27 02:08:52 -07001697 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1698 EXPECT_EQ(111, spec.payload_type);
1699 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001700 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701}
1702
1703// Test that we handle various ways of specifying bitrate.
1704TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001705 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001706 cricket::AudioSendParameters parameters;
1707 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001708 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001709 {
ossu20a4b3f2017-04-27 02:08:52 -07001710 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1711 EXPECT_EQ(103, spec.payload_type);
1712 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1713 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001714 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001716 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001717 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001718 {
ossu20a4b3f2017-04-27 02:08:52 -07001719 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1720 EXPECT_EQ(103, spec.payload_type);
1721 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1722 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001723 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001724 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001726 {
ossu20a4b3f2017-04-27 02:08:52 -07001727 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1728 EXPECT_EQ(103, spec.payload_type);
1729 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1730 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001731 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001733 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001735 {
ossu20a4b3f2017-04-27 02:08:52 -07001736 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1737 EXPECT_EQ(0, spec.payload_type);
1738 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1739 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001740 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001741
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001744 {
ossu20a4b3f2017-04-27 02:08:52 -07001745 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1746 EXPECT_EQ(0, spec.payload_type);
1747 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1748 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001749 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 parameters.codecs[0] = kOpusCodec;
1752 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001753 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001754 {
ossu20a4b3f2017-04-27 02:08:52 -07001755 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1756 EXPECT_EQ(111, spec.payload_type);
1757 EXPECT_STREQ("opus", spec.format.name.c_str());
1758 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001759 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760}
1761
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001762// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001764 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 cricket::AudioSendParameters parameters;
1766 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001767}
1768
1769// Test that we can set send codecs even with telephone-event codec as the first
1770// one on the list.
1771TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001772 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001773 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001774 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 parameters.codecs.push_back(kIsacCodec);
1776 parameters.codecs.push_back(kPcmuCodec);
1777 parameters.codecs[0].id = 98; // DTMF
1778 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001779 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001780 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1781 EXPECT_EQ(96, spec.payload_type);
1782 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001783 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001784 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001785}
1786
Harald Alvestranda1f66612018-02-21 11:24:23 +01001787// Test that CanInsertDtmf() is governed by the send flag
1788TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1789 EXPECT_TRUE(SetupSendStream());
1790 cricket::AudioSendParameters parameters;
1791 parameters.codecs.push_back(kTelephoneEventCodec1);
1792 parameters.codecs.push_back(kPcmuCodec);
1793 parameters.codecs[0].id = 98; // DTMF
1794 parameters.codecs[1].id = 96;
1795 SetSendParameters(parameters);
1796 EXPECT_FALSE(channel_->CanInsertDtmf());
1797 SetSend(true);
1798 EXPECT_TRUE(channel_->CanInsertDtmf());
1799 SetSend(false);
1800 EXPECT_FALSE(channel_->CanInsertDtmf());
1801}
1802
solenberg31642aa2016-03-14 08:00:37 -07001803// Test that payload type range is limited for telephone-event codec.
1804TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001805 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001806 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001807 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001808 parameters.codecs.push_back(kIsacCodec);
1809 parameters.codecs[0].id = 0; // DTMF
1810 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001811 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001812 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001813 EXPECT_TRUE(channel_->CanInsertDtmf());
1814 parameters.codecs[0].id = 128; // DTMF
1815 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1816 EXPECT_FALSE(channel_->CanInsertDtmf());
1817 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001818 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001819 EXPECT_TRUE(channel_->CanInsertDtmf());
1820 parameters.codecs[0].id = -1; // DTMF
1821 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1822 EXPECT_FALSE(channel_->CanInsertDtmf());
1823}
1824
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001825// Test that we can set send codecs even with CN codec as the first
1826// one on the list.
1827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001828 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 cricket::AudioSendParameters parameters;
1830 parameters.codecs.push_back(kCn16000Codec);
1831 parameters.codecs.push_back(kIsacCodec);
1832 parameters.codecs.push_back(kPcmuCodec);
1833 parameters.codecs[0].id = 98; // wideband CN
1834 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001836 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1837 EXPECT_EQ(96, send_codec_spec.payload_type);
1838 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001839 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840}
1841
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001842// Test that we set VAD and DTMF types correctly as caller.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
1846 parameters.codecs.push_back(kIsacCodec);
1847 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001848 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001849 parameters.codecs.push_back(kCn16000Codec);
1850 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001851 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 parameters.codecs[0].id = 96;
1853 parameters.codecs[2].id = 97; // wideband CN
1854 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001855 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001856 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1857 EXPECT_EQ(96, send_codec_spec.payload_type);
1858 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1859 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001860 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001861 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001862 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001863}
1864
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001865// Test that we set VAD and DTMF types correctly as callee.
1866TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001867 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001868 cricket::AudioSendParameters parameters;
1869 parameters.codecs.push_back(kIsacCodec);
1870 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001871 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001872 parameters.codecs.push_back(kCn16000Codec);
1873 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001874 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001875 parameters.codecs[0].id = 96;
1876 parameters.codecs[2].id = 97; // wideband CN
1877 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001878 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001879 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001880 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001881
ossu20a4b3f2017-04-27 02:08:52 -07001882 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1883 EXPECT_EQ(96, send_codec_spec.payload_type);
1884 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1885 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001886 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001887 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001888 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001889}
1890
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001891// Test that we only apply VAD if we have a CN codec that matches the
1892// send codec clockrate.
1893TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001894 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001895 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001897 parameters.codecs.push_back(kIsacCodec);
1898 parameters.codecs.push_back(kCn16000Codec);
1899 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001901 {
ossu20a4b3f2017-04-27 02:08:52 -07001902 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1903 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1904 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001906 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001909 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001910 {
ossu20a4b3f2017-04-27 02:08:52 -07001911 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1912 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001913 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001914 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001915 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001916 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001917 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001918 {
ossu20a4b3f2017-04-27 02:08:52 -07001919 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1920 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1921 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001922 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001923 }
Brave Yao5225dd82015-03-26 07:39:19 +08001924 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001925 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001926 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001927 {
ossu20a4b3f2017-04-27 02:08:52 -07001928 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1929 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001930 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001931 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001932}
1933
1934// Test that we perform case-insensitive matching of codec names.
1935TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001936 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 cricket::AudioSendParameters parameters;
1938 parameters.codecs.push_back(kIsacCodec);
1939 parameters.codecs.push_back(kPcmuCodec);
1940 parameters.codecs.push_back(kCn16000Codec);
1941 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001942 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001943 parameters.codecs[0].name = "iSaC";
1944 parameters.codecs[0].id = 96;
1945 parameters.codecs[2].id = 97; // wideband CN
1946 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001948 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1949 EXPECT_EQ(96, send_codec_spec.payload_type);
1950 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1951 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001952 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001953 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001954 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955}
1956
stefanba4c0e42016-02-04 04:12:24 -08001957class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1958 public:
1959 WebRtcVoiceEngineWithSendSideBweTest()
1960 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1961};
1962
1963TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1964 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001965 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001966 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001967 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1968 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1969 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001970 extension.id);
1971 return;
1972 }
1973 }
1974 FAIL() << "Transport sequence number extension not in header-extension list.";
1975}
1976
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001977// Test support for audio level header extension.
1978TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001979 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001980}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001981TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001982 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001983}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001984
solenbergd4adce42016-11-17 06:26:52 -08001985// Test support for transport sequence number header extension.
1986TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1987 TestSetSendRtpHeaderExtensions(
1988 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001989}
solenbergd4adce42016-11-17 06:26:52 -08001990TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1991 TestSetRecvRtpHeaderExtensions(
1992 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001993}
1994
solenberg1ac56142015-10-13 03:58:19 -07001995// Test that we can create a channel and start sending on it.
1996TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001997 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001998 SetSendParameters(send_parameters_);
1999 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002000 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002001 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002002 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002003}
2004
2005// Test that a channel will send if and only if it has a source and is enabled
2006// for sending.
2007TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002008 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002009 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002010 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002011 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002012 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2013 SetAudioSend(kSsrcX, true, &fake_source_);
2014 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2015 SetAudioSend(kSsrcX, true, nullptr);
2016 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002017}
2018
solenberg94218532016-06-16 10:53:22 -07002019// Test that a channel is muted/unmuted.
2020TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2021 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002022 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002023 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2024 SetAudioSend(kSsrcX, true, nullptr);
2025 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2026 SetAudioSend(kSsrcX, false, nullptr);
2027 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002028}
2029
solenberg6d6e7c52016-04-13 09:07:30 -07002030// Test that SetSendParameters() does not alter a stream's send state.
2031TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2032 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002033 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002034
2035 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002036 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002037 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002038
2039 // Changing RTP header extensions will recreate the AudioSendStream.
2040 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002041 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002042 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002043 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002044
2045 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002046 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002047 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002048
2049 // Changing RTP header extensions will recreate the AudioSendStream.
2050 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002051 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002052 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002053}
2054
solenberg1ac56142015-10-13 03:58:19 -07002055// Test that we can create a channel and start playing out on it.
2056TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002057 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002058 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002059 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002060 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002061 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002062 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002063}
2064
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002065// Test that we can add and remove send streams.
2066TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2067 SetupForMultiSendStream();
2068
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002070 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071
solenbergc96df772015-10-21 13:01:53 -07002072 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002074 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002075 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002076 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002077 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002078 }
tfarina5237aaf2015-11-10 23:44:30 -08002079 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080
solenbergc96df772015-10-21 13:01:53 -07002081 // Delete the send streams.
2082 for (uint32_t ssrc : kSsrcs4) {
2083 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002084 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002085 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002086 }
solenbergc96df772015-10-21 13:01:53 -07002087 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088}
2089
2090// Test SetSendCodecs correctly configure the codecs in all send streams.
2091TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2092 SetupForMultiSendStream();
2093
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002095 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002097 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002098 }
2099
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002100 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002102 parameters.codecs.push_back(kIsacCodec);
2103 parameters.codecs.push_back(kCn16000Codec);
2104 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002105 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106
2107 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002108 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002109 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2110 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002111 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2112 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2113 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002114 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 }
2116
minyue7a973442016-10-20 03:27:12 -07002117 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002118 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002120 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002121 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2122 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002123 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2124 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002125 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 }
2127}
2128
2129// Test we can SetSend on all send streams correctly.
2130TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2131 SetupForMultiSendStream();
2132
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002133 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002134 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002136 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002137 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002138 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 }
2140
2141 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002142 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002143 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002145 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 }
2147
2148 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002149 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002150 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002151 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002152 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
2154}
2155
2156// Test we can set the correct statistics on all send streams.
2157TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2158 SetupForMultiSendStream();
2159
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002160 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002161 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002163 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164 }
solenberg85a04962015-10-27 03:35:21 -07002165
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002166 // Create a receive stream to check that none of the send streams end up in
2167 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002169
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002171 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002172 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002173 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002174
solenberg85a04962015-10-27 03:35:21 -07002175 // Check stats for the added streams.
2176 {
2177 cricket::VoiceMediaInfo info;
2178 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179
solenberg85a04962015-10-27 03:35:21 -07002180 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002181 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002182 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002183 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002184 }
hbos1acfbd22016-11-17 23:43:29 -08002185 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002186
2187 // We have added one receive stream. We should see empty stats.
2188 EXPECT_EQ(info.receivers.size(), 1u);
2189 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
solenberg1ac56142015-10-13 03:58:19 -07002191
solenberg2100c0b2017-03-01 11:29:29 -08002192 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002193 {
2194 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002195 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002196 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002197 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002198 EXPECT_EQ(0u, info.receivers.size());
2199 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002200
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002201 // Deliver a new packet - a default receive stream should be created and we
2202 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002203 {
2204 cricket::VoiceMediaInfo info;
2205 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2206 SetAudioReceiveStreamStats();
2207 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002208 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002209 EXPECT_EQ(1u, info.receivers.size());
2210 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002211 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002212 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213}
2214
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002215// Test that we can add and remove receive streams, and do proper send/playout.
2216// We can receive on multiple streams while sending one stream.
2217TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002218 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002219
solenberg1ac56142015-10-13 03:58:19 -07002220 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002221 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002222 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002223
solenberg1ac56142015-10-13 03:58:19 -07002224 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002226 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002228
solenberg1ac56142015-10-13 03:58:19 -07002229 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002230 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002231
2232 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002233 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2234 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2235 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002236
2237 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002238 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002239 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002240
2241 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002242 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002243 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2244 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002245
aleloi84ef6152016-08-04 05:28:21 -07002246 // Restart playout and make sure recv streams are played out.
2247 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002248 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2249 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250
aleloi84ef6152016-08-04 05:28:21 -07002251 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002252 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2253 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002254}
2255
wu@webrtc.org97077a32013-10-25 21:18:33 +00002256TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002257 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002258 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2259 .Times(1)
2260 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002261 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2262 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002263 send_parameters_.options.tx_agc_target_dbov = 3;
2264 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2265 send_parameters_.options.tx_agc_limiter = true;
2266 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002267 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2268 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2269 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002270 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002271}
2272
minyue6b825df2016-10-31 04:08:32 -07002273TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2274 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002275 send_parameters_.options.audio_network_adaptor = true;
2276 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002277 SetSendParameters(send_parameters_);
2278 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002279 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002280}
2281
2282TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2283 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002284 send_parameters_.options.audio_network_adaptor = true;
2285 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002286 SetSendParameters(send_parameters_);
2287 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002288 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002289 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002290 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002291 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002292 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002293}
2294
2295TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2296 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002297 send_parameters_.options.audio_network_adaptor = true;
2298 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002299 SetSendParameters(send_parameters_);
2300 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002301 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002302 const int initial_num = call_.GetNumCreatedSendStreams();
2303 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002304 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002305 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2306 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002307 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002308 // AudioSendStream not expected to be recreated.
2309 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2310 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002311 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002312}
2313
michaelt6672b262017-01-11 10:17:59 -08002314class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2315 : public WebRtcVoiceEngineTestFake {
2316 public:
2317 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2318 : WebRtcVoiceEngineTestFake(
2319 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2320 "Enabled/") {}
2321};
2322
2323TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2324 EXPECT_TRUE(SetupSendStream());
2325 cricket::AudioSendParameters parameters;
2326 parameters.codecs.push_back(kOpusCodec);
2327 SetSendParameters(parameters);
2328 const int initial_num = call_.GetNumCreatedSendStreams();
2329 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2330
2331 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2332 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002333 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2334 constexpr int kMinOverheadBps =
2335 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002336
2337 constexpr int kOpusMinBitrateBps = 6000;
2338 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002339 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002340 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002341 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002342 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002343
Oskar Sundbom78807582017-11-16 11:09:55 +01002344 parameters.options.audio_network_adaptor = true;
2345 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002346 SetSendParameters(parameters);
2347
ossu11bfc532017-02-16 05:37:06 -08002348 constexpr int kMinOverheadWithAnaBps =
2349 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002350
2351 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002352 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002353
minyuececec102017-03-27 13:04:25 -07002354 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002355 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002356}
2357
minyuececec102017-03-27 13:04:25 -07002358// This test is similar to
2359// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2360// additional field trial.
2361TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2362 SetRtpSendParameterUpdatesMaxBitrate) {
2363 EXPECT_TRUE(SetupSendStream());
2364 cricket::AudioSendParameters send_parameters;
2365 send_parameters.codecs.push_back(kOpusCodec);
2366 SetSendParameters(send_parameters);
2367
2368 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2369 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2370 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2371
2372 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002373 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002374 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002375
2376 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2377#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2378 constexpr int kMinOverhead = 3333;
2379#else
2380 constexpr int kMinOverhead = 6666;
2381#endif
2382 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2383}
2384
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002386// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002387TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002388 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002389 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002390}
2391
2392TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2393 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002394 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002395 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002396 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002397 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002398 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002399 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002400 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401
solenberg85a04962015-10-27 03:35:21 -07002402 // Check stats for the added streams.
2403 {
2404 cricket::VoiceMediaInfo info;
2405 EXPECT_EQ(true, channel_->GetStats(&info));
2406
2407 // We have added one send stream. We should see the stats we've set.
2408 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002409 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002410 // We have added one receive stream. We should see empty stats.
2411 EXPECT_EQ(info.receivers.size(), 1u);
2412 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2413 }
solenberg1ac56142015-10-13 03:58:19 -07002414
solenberg566ef242015-11-06 15:34:49 -08002415 // Start sending - this affects some reported stats.
2416 {
2417 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002418 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002419 EXPECT_EQ(true, channel_->GetStats(&info));
2420 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002421 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002422 }
2423
solenberg2100c0b2017-03-01 11:29:29 -08002424 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002425 {
2426 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002427 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002428 EXPECT_EQ(true, channel_->GetStats(&info));
2429 EXPECT_EQ(1u, info.senders.size());
2430 EXPECT_EQ(0u, info.receivers.size());
2431 }
solenberg1ac56142015-10-13 03:58:19 -07002432
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002433 // Deliver a new packet - a default receive stream should be created and we
2434 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002435 {
2436 cricket::VoiceMediaInfo info;
2437 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2438 SetAudioReceiveStreamStats();
2439 EXPECT_EQ(true, channel_->GetStats(&info));
2440 EXPECT_EQ(1u, info.senders.size());
2441 EXPECT_EQ(1u, info.receivers.size());
2442 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002443 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002444 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445}
2446
2447// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002448// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002450 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002451 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2452 EXPECT_TRUE(AddRecvStream(kSsrcY));
2453 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454}
2455
2456// Test that the local SSRC is the same on sending and receiving channels if the
2457// receive channel is created before the send channel.
2458TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002459 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002460 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002462 cricket::StreamParams::CreateLegacy(kSsrcX)));
2463 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2464 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465}
2466
2467// Test that we can properly receive packets.
2468TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002469 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002470 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002472
2473 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2474 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475}
2476
2477// Test that we can properly receive packets on multiple streams.
2478TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002479 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002480 const uint32_t ssrc1 = 1;
2481 const uint32_t ssrc2 = 2;
2482 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002483 EXPECT_TRUE(AddRecvStream(ssrc1));
2484 EXPECT_TRUE(AddRecvStream(ssrc2));
2485 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002487 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002488 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002490 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491 }
mflodman3d7db262016-04-29 00:57:13 -07002492
2493 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2494 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2495 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2496
2497 EXPECT_EQ(s1.received_packets(), 0);
2498 EXPECT_EQ(s2.received_packets(), 0);
2499 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002500
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002502 EXPECT_EQ(s1.received_packets(), 0);
2503 EXPECT_EQ(s2.received_packets(), 0);
2504 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002505
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002507 EXPECT_EQ(s1.received_packets(), 1);
2508 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2509 EXPECT_EQ(s2.received_packets(), 0);
2510 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002511
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002513 EXPECT_EQ(s1.received_packets(), 1);
2514 EXPECT_EQ(s2.received_packets(), 1);
2515 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2516 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002517
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002518 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002519 EXPECT_EQ(s1.received_packets(), 1);
2520 EXPECT_EQ(s2.received_packets(), 1);
2521 EXPECT_EQ(s3.received_packets(), 1);
2522 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002523
mflodman3d7db262016-04-29 00:57:13 -07002524 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2525 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2526 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527}
2528
solenberg2100c0b2017-03-01 11:29:29 -08002529// Test that receiving on an unsignaled stream works (a stream is created).
2530TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002531 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002532 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2533
solenberg7e63ef02015-11-20 00:19:43 -08002534 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002535
2536 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002537 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2538 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002539}
2540
solenberg2100c0b2017-03-01 11:29:29 -08002541// Test that receiving N unsignaled stream works (streams will be created), and
2542// that packets are forwarded to them all.
2543TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002544 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002545 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002546 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2547
solenberg2100c0b2017-03-01 11:29:29 -08002548 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002549 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002550 rtc::SetBE32(&packet[8], ssrc);
2551 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002552
solenberg2100c0b2017-03-01 11:29:29 -08002553 // Verify we have one new stream for each loop iteration.
2554 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002555 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2556 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002557 }
mflodman3d7db262016-04-29 00:57:13 -07002558
solenberg2100c0b2017-03-01 11:29:29 -08002559 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002560 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002561 rtc::SetBE32(&packet[8], ssrc);
2562 DeliverPacket(packet, sizeof(packet));
2563
solenbergebb349d2017-03-13 05:46:15 -07002564 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002565 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2566 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2567 }
2568
2569 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2570 constexpr uint32_t kAnotherSsrc = 667;
2571 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002572 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002573
2574 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002575 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002576 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002577 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002578 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2579 EXPECT_EQ(2, streams[i]->received_packets());
2580 }
2581 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2582 EXPECT_EQ(1, streams[i]->received_packets());
2583 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002584 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002585}
2586
solenberg2100c0b2017-03-01 11:29:29 -08002587// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002588// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002589TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002590 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002591 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002592 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2593
2594 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002595 const uint32_t signaled_ssrc = 1;
2596 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002597 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002598 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002599 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2600 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002601 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002602
2603 // Note that the first unknown SSRC cannot be 0, because we only support
2604 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002605 const uint32_t unsignaled_ssrc = 7011;
2606 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002607 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002608 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2609 packet, sizeof(packet)));
2610 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2611
2612 DeliverPacket(packet, sizeof(packet));
2613 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2614
2615 rtc::SetBE32(&packet[8], signaled_ssrc);
2616 DeliverPacket(packet, sizeof(packet));
2617 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2618 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002619}
2620
solenberg4904fb62017-02-17 12:01:14 -08002621// Two tests to verify that adding a receive stream with the same SSRC as a
2622// previously added unsignaled stream will only recreate underlying stream
2623// objects if the stream parameters have changed.
2624TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2625 EXPECT_TRUE(SetupChannel());
2626
2627 // Spawn unsignaled stream with SSRC=1.
2628 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2629 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2630 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2631 sizeof(kPcmuFrame)));
2632
2633 // Verify that the underlying stream object in Call is not recreated when a
2634 // stream with SSRC=1 is added.
2635 const auto& streams = call_.GetAudioReceiveStreams();
2636 EXPECT_EQ(1, streams.size());
2637 int audio_receive_stream_id = streams.front()->id();
2638 EXPECT_TRUE(AddRecvStream(1));
2639 EXPECT_EQ(1, streams.size());
2640 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2641}
2642
2643TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2644 EXPECT_TRUE(SetupChannel());
2645
2646 // Spawn unsignaled stream with SSRC=1.
2647 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2648 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2649 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2650 sizeof(kPcmuFrame)));
2651
2652 // Verify that the underlying stream object in Call *is* recreated when a
2653 // stream with SSRC=1 is added, and which has changed stream parameters.
2654 const auto& streams = call_.GetAudioReceiveStreams();
2655 EXPECT_EQ(1, streams.size());
2656 int audio_receive_stream_id = streams.front()->id();
2657 cricket::StreamParams stream_params;
2658 stream_params.ssrcs.push_back(1);
2659 stream_params.sync_label = "sync_label";
2660 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2661 EXPECT_EQ(1, streams.size());
2662 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2663}
2664
solenberg1ac56142015-10-13 03:58:19 -07002665// Test that AddRecvStream creates new stream.
2666TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002667 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669}
2670
2671// Test that after adding a recv stream, we do not decode more codecs than
2672// those previously passed into SetRecvCodecs.
2673TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002675 cricket::AudioRecvParameters parameters;
2676 parameters.codecs.push_back(kIsacCodec);
2677 parameters.codecs.push_back(kPcmuCodec);
2678 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002679 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002680 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2681 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2682 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002683}
2684
2685// Test that we properly clean up any streams that were added, even if
2686// not explicitly removed.
2687TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002689 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002690 EXPECT_TRUE(AddRecvStream(1));
2691 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002692
2693 EXPECT_EQ(1, call_.GetAudioSendStreams().size());
2694 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002695 delete channel_;
2696 channel_ = NULL;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002697 EXPECT_EQ(0, call_.GetAudioSendStreams().size());
2698 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699}
2700
wu@webrtc.org78187522013-10-07 23:32:02 +00002701TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002703 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002704}
2705
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002706TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002707 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002708 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002709 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002710}
2711
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002712// Test the InsertDtmf on default send stream as caller.
2713TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002714 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715}
2716
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002717// Test the InsertDtmf on default send stream as callee
2718TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002719 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002720}
2721
2722// Test the InsertDtmf on specified send stream as caller.
2723TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002724 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002725}
2726
2727// Test the InsertDtmf on specified send stream as callee.
2728TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002729 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730}
2731
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002733 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002734 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002735 EXPECT_CALL(adm_,
2736 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2737 EXPECT_CALL(adm_,
2738 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2739 EXPECT_CALL(adm_,
2740 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002741
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002742 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2743 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744
solenberg246b8172015-12-08 09:50:23 -08002745 // Nothing set in AudioOptions, so everything should be as default.
2746 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002747 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002748 EXPECT_TRUE(IsHighPassFilterEnabled());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002749 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2750 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751
2752 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002753 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002755 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757
2758 // Turn echo cancellation back on, with settings, and make sure
2759 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002762 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002763 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002765 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2766 // control.
solenberg76377c52017-02-21 00:54:31 -08002767 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2768 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002769 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002770 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002771
2772 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002773 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2774 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002775 send_parameters_.options.delay_agnostic_aec = false;
2776 send_parameters_.options.extended_filter_aec = false;
2777 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002778 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002779
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002780 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002781 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002783 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002784 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002785
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002787 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002789 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002790 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002791 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002792 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793
2794 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002795 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002797 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002798 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002799 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002800 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002802 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002803 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2804 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002805 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002806 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002807 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002808 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002810 send_parameters_.options.noise_suppression = false;
2811 send_parameters_.options.highpass_filter = false;
2812 send_parameters_.options.typing_detection = false;
2813 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002814 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002815 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816
solenberg1ac56142015-10-13 03:58:19 -07002817 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002818 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2819 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002820 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002821 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002822 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002823 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2824 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002825 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002826}
2827
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002828TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002829 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002830 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002831 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002832 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002833 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002834 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002835 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002836 EXPECT_CALL(adm_,
2837 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2838 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2839 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002840 webrtc::AudioProcessing::Config apm_config;
2841 EXPECT_CALL(*apm_, GetConfig())
2842 .Times(10)
2843 .WillRepeatedly(ReturnPointee(&apm_config));
2844 EXPECT_CALL(*apm_, ApplyConfig(_))
2845 .Times(10)
2846 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002847 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002848
kwiberg686a8ef2016-02-26 03:00:35 -08002849 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002850 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002851 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002852 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002853 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002854 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002855
2856 // Have to add a stream to make SetSend work.
2857 cricket::StreamParams stream1;
2858 stream1.ssrcs.push_back(1);
2859 channel1->AddSendStream(stream1);
2860 cricket::StreamParams stream2;
2861 stream2.ssrcs.push_back(2);
2862 channel2->AddSendStream(stream2);
2863
2864 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002865 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002866 parameters_options_all.options.echo_cancellation = true;
2867 parameters_options_all.options.auto_gain_control = true;
2868 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002869 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2870 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002871 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002873 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002875 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002876 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002877 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002878 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
2880 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002882 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002885 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002889 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002890 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002891 expected_options.echo_cancellation = true;
2892 expected_options.auto_gain_control = true;
2893 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002894 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002895
2896 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002897 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002898 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002901 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002902 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002903 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002905 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002906 expected_options.echo_cancellation = true;
2907 expected_options.auto_gain_control = false;
2908 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002909 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002913 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002917 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2920 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002921 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002922 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002923 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002924 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002925 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926
solenberg76377c52017-02-21 00:54:31 -08002927 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2928 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002929 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002930 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002931 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002932 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002933 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002934
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2937 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002938 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2939 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2941 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002942 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002943 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002944 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002945 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002946 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002947 expected_options.echo_cancellation = true;
2948 expected_options.auto_gain_control = false;
2949 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002950 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002951}
2952
wu@webrtc.orgde305012013-10-31 15:40:38 +00002953// This test verifies DSCP settings are properly applied on voice media channel.
2954TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002955 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002956 cricket::FakeNetworkInterface network_interface;
2957 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002958 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002959
peahb1c9d1d2017-07-25 15:45:24 -07002960 webrtc::AudioProcessing::Config apm_config;
2961 EXPECT_CALL(*apm_, GetConfig())
2962 .Times(3)
2963 .WillRepeatedly(ReturnPointee(&apm_config));
2964 EXPECT_CALL(*apm_, ApplyConfig(_))
2965 .Times(3)
2966 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002967 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002968
solenbergbc37fc82016-04-04 09:54:44 -07002969 channel.reset(
2970 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002971 channel->SetInterface(&network_interface);
2972 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2973 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2974
2975 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002976 channel.reset(
2977 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002978 channel->SetInterface(&network_interface);
2979 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2980
2981 // Verify that setting the option to false resets the
2982 // DiffServCodePoint.
2983 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002984 channel.reset(
2985 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002986 channel->SetInterface(&network_interface);
2987 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2988 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2989
2990 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002991}
2992
solenberg4bac9c52015-10-09 02:32:53 -07002993TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002994 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002995 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002997 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002999 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3000 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3001 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003002}
3003
solenberg2100c0b2017-03-01 11:29:29 -08003004TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003005 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003006
3007 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003008 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003009 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3010
3011 // Should remember the volume "2" which will be set on new unsignaled streams,
3012 // and also set the gain to 2 on existing unsignaled streams.
3013 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3014 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3015
3016 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3017 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3018 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3019 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3020 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3021 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3022
3023 // Setting gain with SSRC=0 should affect all unsignaled streams.
3024 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003025 if (kMaxUnsignaledRecvStreams > 1) {
3026 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3027 }
solenberg2100c0b2017-03-01 11:29:29 -08003028 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3029
3030 // Setting gain on an individual stream affects only that.
3031 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003032 if (kMaxUnsignaledRecvStreams > 1) {
3033 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3034 }
solenberg2100c0b2017-03-01 11:29:29 -08003035 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003036}
3037
pbos8fc7fa72015-07-15 08:02:58 -07003038TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003039 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003040 const std::string kSyncLabel = "AvSyncLabel";
3041
solenbergff976312016-03-30 23:28:51 -07003042 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003043 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3044 sp.sync_label = kSyncLabel;
3045 // Creating two channels to make sure that sync label is set properly for both
3046 // the default voice channel and following ones.
3047 EXPECT_TRUE(channel_->AddRecvStream(sp));
3048 sp.ssrcs[0] += 1;
3049 EXPECT_TRUE(channel_->AddRecvStream(sp));
3050
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003051 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003052 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003053 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003054 << "SyncGroup should be set based on sync_label";
3055 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003056 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003057 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003058}
3059
solenberg3a941542015-11-16 07:34:50 -08003060// TODO(solenberg): Remove, once recv streams are configured through Call.
3061// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003062TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003063 // Test that setting the header extensions results in the expected state
3064 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003065 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003066 ssrcs.push_back(223);
3067 ssrcs.push_back(224);
3068
solenbergff976312016-03-30 23:28:51 -07003069 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003070 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003071 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003072 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003073 cricket::StreamParams::CreateLegacy(ssrc)));
3074 }
3075
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003076 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003077 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003078 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003079 EXPECT_NE(nullptr, s);
3080 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3081 }
3082
3083 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003084 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003085 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003086 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003087 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003088 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003089 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003090 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 EXPECT_NE(nullptr, s);
3092 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003093 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3094 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 for (const auto& s_ext : s_exts) {
3096 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003097 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 }
3099 }
3100 }
3101 }
3102
3103 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003104 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003105 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003106 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107 EXPECT_NE(nullptr, s);
3108 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3109 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003110}
3111
3112TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3113 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003114 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003115 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003116 static const unsigned char kRtcp[] = {
3117 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3118 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3121 };
jbaucheec21bd2016-03-20 06:15:43 -07003122 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123
solenbergff976312016-03-30 23:28:51 -07003124 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 cricket::WebRtcVoiceMediaChannel* media_channel =
3126 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003127 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 EXPECT_TRUE(media_channel->AddRecvStream(
3129 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3130
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003131 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003132 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003133 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134 EXPECT_EQ(0, s->received_packets());
3135 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3136 EXPECT_EQ(1, s->received_packets());
3137 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3138 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139}
Minyue2013aec2015-05-13 14:14:42 +02003140
solenberg0a617e22015-10-20 15:49:38 -07003141// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003142// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003143TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003144 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003145 EXPECT_TRUE(AddRecvStream(kSsrcY));
3146 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003147 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003148 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3149 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3150 EXPECT_TRUE(AddRecvStream(kSsrcW));
3151 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003152}
3153
solenberg7602aab2016-11-14 11:30:07 -08003154TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3155 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003156 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003157 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003158 cricket::StreamParams::CreateLegacy(kSsrcY)));
3159 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3160 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3161 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003162 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003163 cricket::StreamParams::CreateLegacy(kSsrcW)));
3164 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3165 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003166}
stefan658910c2015-09-03 05:48:32 -07003167
deadbeef884f5852016-01-15 09:20:04 -08003168TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003169 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003170 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3171 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003172
3173 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003174 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3175 EXPECT_TRUE(AddRecvStream(kSsrcX));
3176 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003177
3178 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003179 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3180 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003181
3182 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003183 channel_->SetRawAudioSink(kSsrcX, nullptr);
3184 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003185}
3186
solenberg2100c0b2017-03-01 11:29:29 -08003187TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003188 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003189 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3190 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003191 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3192 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003193
3194 // Should be able to set a default sink even when no stream exists.
3195 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3196
solenberg2100c0b2017-03-01 11:29:29 -08003197 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3198 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003199 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003200 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003201
3202 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003203 channel_->SetRawAudioSink(kSsrc0, nullptr);
3204 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003207 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3208 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003209
3210 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003212 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003213 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3214
3215 // Spawn another unsignaled stream - it should be assigned the default sink
3216 // and the previous unsignaled stream should lose it.
3217 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3218 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3219 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3220 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003221 if (kMaxUnsignaledRecvStreams > 1) {
3222 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3223 }
solenberg2100c0b2017-03-01 11:29:29 -08003224 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3225
3226 // Reset the default sink - the second unsignaled stream should lose it.
3227 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3230 }
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3232
3233 // Try setting the default sink while two streams exists.
3234 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3237 }
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3239
3240 // Try setting the sink for the first unsignaled stream using its known SSRC.
3241 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003242 if (kMaxUnsignaledRecvStreams > 1) {
3243 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3244 }
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003246 if (kMaxUnsignaledRecvStreams > 1) {
3247 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3248 }
deadbeef884f5852016-01-15 09:20:04 -08003249}
3250
skvlad7a43d252016-03-22 15:32:27 -07003251// Test that, just like the video channel, the voice channel communicates the
3252// network state to the call.
3253TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003254 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003255
3256 EXPECT_EQ(webrtc::kNetworkUp,
3257 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3258 EXPECT_EQ(webrtc::kNetworkUp,
3259 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3260
3261 channel_->OnReadyToSend(false);
3262 EXPECT_EQ(webrtc::kNetworkDown,
3263 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3264 EXPECT_EQ(webrtc::kNetworkUp,
3265 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3266
3267 channel_->OnReadyToSend(true);
3268 EXPECT_EQ(webrtc::kNetworkUp,
3269 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3270 EXPECT_EQ(webrtc::kNetworkUp,
3271 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3272}
3273
aleloi18e0b672016-10-04 02:45:47 -07003274// Test that playout is still started after changing parameters
3275TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3276 SetupRecvStream();
3277 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003279
3280 // Changing RTP header extensions will recreate the AudioReceiveStream.
3281 cricket::AudioRecvParameters parameters;
3282 parameters.extensions.push_back(
3283 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3284 channel_->SetRecvParameters(parameters);
3285
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003287}
3288
Zhi Huangfa266ef2017-12-13 10:27:46 -08003289// Tests when GetSources is called with non-existing ssrc, it will return an
3290// empty list of RtpSource without crashing.
3291TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3292 // Setup an recv stream with |kSsrcX|.
3293 SetupRecvStream();
3294 cricket::WebRtcVoiceMediaChannel* media_channel =
3295 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3296 // Call GetSources with |kSsrcY| which doesn't exist.
3297 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3298 EXPECT_EQ(0u, sources.size());
3299}
3300
stefan658910c2015-09-03 05:48:32 -07003301// Tests that the library initializes and shuts down properly.
3302TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003303 // If the VoiceEngine wants to gather available codecs early, that's fine but
3304 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003305 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003306 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003307 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003308 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003309 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003310 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003311 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003312 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003313 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003314 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003315 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3316 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003317 EXPECT_TRUE(channel != nullptr);
3318 delete channel;
solenbergff976312016-03-30 23:28:51 -07003319}
stefan658910c2015-09-03 05:48:32 -07003320
solenbergff976312016-03-30 23:28:51 -07003321// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003322TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3323 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003324 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003325 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003326 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003327 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003328 {
peaha9cc40b2017-06-29 08:32:09 -07003329 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003330 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003331 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003332 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003333 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003334 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003335 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003336 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003337 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003338 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3339 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3340 EXPECT_TRUE(channel != nullptr);
3341 delete channel;
3342 }
stefan658910c2015-09-03 05:48:32 -07003343}
3344
ossu20a4b3f2017-04-27 02:08:52 -07003345// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3346TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003347 // TODO(ossu): Why are the payload types of codecs with non-static payload
3348 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003349 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003350 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003351 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003352 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003353 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003354 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003355 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003356 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003357 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3358 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3359 (clockrate == 0 || codec.clockrate == clockrate);
3360 };
3361 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003362 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003363 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003364 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003365 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003366 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003367 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003368 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003369 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003370 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(126, codec.id);
3373 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3374 // Remove these checks once both send and receive side assigns payload types
3375 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003376 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003382 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(111, codec.id);
3384 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3385 EXPECT_EQ("10", codec.params.find("minptime")->second);
3386 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3387 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003388 }
3389 }
stefan658910c2015-09-03 05:48:32 -07003390}
3391
3392// Tests that VoE supports at least 32 channels
3393TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003394 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003395 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003396 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003397 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003398 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003399 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003400 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003401 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003402 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003403 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003404
3405 cricket::VoiceMediaChannel* channels[32];
3406 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003407 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003408 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3409 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003410 if (!channel)
3411 break;
stefan658910c2015-09-03 05:48:32 -07003412 channels[num_channels++] = channel;
3413 }
3414
tfarina5237aaf2015-11-10 23:44:30 -08003415 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003416 EXPECT_EQ(expected, num_channels);
3417
3418 while (num_channels > 0) {
3419 delete channels[--num_channels];
3420 }
stefan658910c2015-09-03 05:48:32 -07003421}
3422
3423// Test that we set our preferred codecs properly.
3424TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003425 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3426 // - Check that our builtin codecs are usable by Channel.
3427 // - The codecs provided by the engine is usable by Channel.
3428 // It does not check that the codecs in the RecvParameters are actually
3429 // what we sent in - though it's probably reasonable to expect so, if
3430 // SetRecvParameters returns true.
3431 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003432 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003433 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003434 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003435 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003436 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003437 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003438 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003439 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003440 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003441 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003442 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3443 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003444 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003445 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003446 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003447}
ossu9def8002017-02-09 05:14:32 -08003448
3449TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3450 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003451 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3452 {48000, 2, 16000, 10000, 20000}};
3453 spec1.info.allow_comfort_noise = false;
3454 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003455 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003456 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3457 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003458 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003459 specs.push_back(webrtc::AudioCodecSpec{
3460 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3461 {16000, 1, 13300}});
3462 specs.push_back(
3463 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3464 specs.push_back(
3465 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003466
ossueb1fde42017-05-02 06:46:30 -07003467 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3468 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3469 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003470 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003471 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003472 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003473 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003474
peaha9cc40b2017-06-29 08:32:09 -07003475 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003476 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003477 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003478 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003479 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003480 auto codecs = engine.recv_codecs();
3481 EXPECT_EQ(11, codecs.size());
3482
3483 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3484 // check the actual values safely, to provide better test results.
3485 auto get_codec =
3486 [&codecs](size_t index) -> const cricket::AudioCodec& {
3487 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3488 if (codecs.size() > index)
3489 return codecs[index];
3490 return missing_codec;
3491 };
3492
3493 // Ensure the general codecs are generated first and in order.
3494 for (size_t i = 0; i != specs.size(); ++i) {
3495 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3496 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3497 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3498 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3499 }
3500
3501 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003502 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003503 auto find_codec =
3504 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3505 for (size_t i = 0; i != codecs.size(); ++i) {
3506 const cricket::AudioCodec& codec = codecs[i];
3507 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3508 codec.clockrate == format.clockrate_hz &&
3509 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003510 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003511 }
3512 }
3513 return -1;
3514 };
3515
3516 // Ensure all supplementary codecs are generated last. Their internal ordering
3517 // is not important.
3518 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3519 const int num_specs = static_cast<int>(specs.size());
3520 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3521 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3522 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3523 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3524 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3525 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3526 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3527}