blob: 79fe7c7ce60573930346ccc4c1da240568f22aea [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010039using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010046using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020047
solenberg418b7d32017-06-13 00:38:27 -070048constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070049
deadbeef67cf2c12016-04-13 10:07:16 -070050const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
51const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070052const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
54const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070055const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
56const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080057const cricket::AudioCodec
58 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
59const cricket::AudioCodec
60 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
61
solenberg2100c0b2017-03-01 11:29:29 -080062const uint32_t kSsrc0 = 0;
63const uint32_t kSsrc1 = 1;
64const uint32_t kSsrcX = 0x99;
65const uint32_t kSsrcY = 0x17;
66const uint32_t kSsrcZ = 0x42;
67const uint32_t kSsrcW = 0x02;
68const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
solenberg971cab02016-06-14 10:02:41 -070070constexpr int kRtpHistoryMs = 5000;
71
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010072constexpr webrtc::GainControl::Mode kDefaultAgcMode =
73#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
74 webrtc::GainControl::kFixedDigital;
75#else
76 webrtc::GainControl::kAdaptiveAnalog;
77#endif
78
79constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
80 webrtc::NoiseSuppression::kHigh;
81
solenberg9a5f032222017-03-15 06:14:12 -070082void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
83 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010084
85 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010086 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010087 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010088 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070089#if defined(WEBRTC_WIN)
90 EXPECT_CALL(*adm, SetPlayoutDevice(
91 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
92 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
93 .WillOnce(Return(0));
94#else
95 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
96#endif // #if defined(WEBRTC_WIN)
97 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
98 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
99 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100100#if defined(WEBRTC_WIN)
101 EXPECT_CALL(*adm, SetRecordingDevice(
102 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
103 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
104 .WillOnce(Return(0));
105#else
106 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
107#endif // #if defined(WEBRTC_WIN)
108 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
109 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
110 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700111 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114
115 // Teardown.
116 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
118 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
119 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100120 EXPECT_CALL(*adm, Release()).Times(3)
121 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700122}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200123} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124
solenbergff976312016-03-30 23:28:51 -0700125// Tests that our stub library "works".
126TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700127 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700128 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700129 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
130 new rtc::RefCountedObject<
131 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700132 webrtc::AudioProcessing::Config apm_config;
133 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
134 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700135 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700136 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700137 {
ossuc54071d2016-08-17 02:45:41 -0700138 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700139 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100140 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700141 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700142 }
solenbergff976312016-03-30 23:28:51 -0700143}
144
deadbeef884f5852016-01-15 09:20:04 -0800145class FakeAudioSink : public webrtc::AudioSinkInterface {
146 public:
147 void OnData(const Data& audio) override {}
148};
149
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800150class FakeAudioSource : public cricket::AudioSource {
151 void SetSink(Sink* sink) override {}
152};
153
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154class WebRtcVoiceEngineTestFake : public testing::Test {
155 public:
stefanba4c0e42016-02-04 04:12:24 -0800156 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
157
158 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700159 : apm_(new rtc::RefCountedObject<
160 StrictMock<webrtc::test::MockAudioProcessing>>()),
161 apm_gc_(*apm_->gain_control()),
162 apm_ec_(*apm_->echo_cancellation()),
163 apm_ns_(*apm_->noise_suppression()),
164 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100165 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700166 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800167 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700168 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800169 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700170 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
171 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700172 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700173 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800174 // Default Options.
175 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
176 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100177 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
178 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800179 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100180 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
181 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800182 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
183 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800184 // Init does not overwrite default AGC config.
185 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
186 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
187 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800188 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
189 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700190 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800191 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700192 // factories. Those tests should probably be moved elsewhere.
193 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
194 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100195 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100196 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700197 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200198 send_parameters_.codecs.push_back(kPcmuCodec);
199 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100200
solenberg76377c52017-02-21 00:54:31 -0800201 // Default Options.
202 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 }
solenberg8189b022016-06-14 12:13:00 -0700204
solenbergff976312016-03-30 23:28:51 -0700205 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700206 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700207 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
208 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200209 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupRecvStream() {
213 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700214 return false;
215 }
solenberg2100c0b2017-03-01 11:29:29 -0800216 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200220 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
221 }
222
223 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700224 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000225 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 }
Florent Castellidacec712018-05-24 16:24:21 +0200227 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800228 return false;
229 }
peaha9cc40b2017-06-29 08:32:09 -0700230 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800231 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
234 bool AddRecvStream(uint32_t ssrc) {
235 EXPECT_TRUE(channel_);
236 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
237 }
238
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000239 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700240 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700241 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800242 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
243 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700244 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800245 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246 }
solenberg8189b022016-06-14 12:13:00 -0700247
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700249 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 }
solenberg8189b022016-06-14 12:13:00 -0700252
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200253 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 }
256
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100257 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
258 const auto* send_stream = call_.GetAudioSendStream(ssrc);
259 EXPECT_TRUE(send_stream);
260 return *send_stream;
261 }
262
deadbeef884f5852016-01-15 09:20:04 -0800263 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
264 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
265 EXPECT_TRUE(recv_stream);
266 return *recv_stream;
267 }
268
solenberg3a941542015-11-16 07:34:50 -0800269 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800270 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800271 }
272
solenberg7add0582015-11-20 09:59:34 -0800273 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800274 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800275 }
276
solenberg059fb442016-10-26 05:12:24 -0700277 void SetSend(bool enable) {
278 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700279 if (enable) {
280 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
281 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
282 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700283 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700284 }
solenberg059fb442016-10-26 05:12:24 -0700285 channel_->SetSend(enable);
286 }
287
288 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700289 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700290 ASSERT_TRUE(channel_);
291 EXPECT_TRUE(channel_->SetSendParameters(params));
292 }
293
minyue6b825df2016-10-31 04:08:32 -0700294 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
295 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700296 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700297 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700298 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700299 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700300 }
301 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700302 }
303
solenbergffbbcac2016-11-17 05:25:37 -0800304 void TestInsertDtmf(uint32_t ssrc, bool caller,
305 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700306 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000307 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700308 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000309 // send stream.
310 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800311 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700315 SetSendParameters(send_parameters_);
316 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800318 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800319 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700320 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322
323 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700324 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800325 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800327 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328 }
329
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100333 // Test send.
334 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800335 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100336 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800337 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800338 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800339 EXPECT_EQ(codec.id, telephone_event.payload_type);
340 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 EXPECT_EQ(2, telephone_event.event_code);
342 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 }
344
345 // Test that send bandwidth is set correctly.
346 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000347 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
348 // |expected_result| is the expected result from SetMaxSendBandwidth().
349 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700350 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
351 int max_bitrate,
352 bool expected_result,
353 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200354 cricket::AudioSendParameters parameters;
355 parameters.codecs.push_back(codec);
356 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700357 if (expected_result) {
358 SetSendParameters(parameters);
359 } else {
360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
361 }
solenberg2100c0b2017-03-01 11:29:29 -0800362 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 }
364
skvlade0d46372016-04-07 22:59:22 -0700365 // Sets the per-stream maximum bitrate limit for the specified SSRC.
366 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700367 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700368 EXPECT_EQ(1UL, parameters.encodings.size());
369
Oskar Sundbom78807582017-11-16 11:09:55 +0100370 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800371 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700372 }
373
solenberg059fb442016-10-26 05:12:24 -0700374 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700375 cricket::AudioSendParameters send_parameters;
376 send_parameters.codecs.push_back(codec);
377 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700378 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700379 }
380
ossu20a4b3f2017-04-27 02:08:52 -0700381 void CheckSendCodecBitrate(int32_t ssrc,
382 const char expected_name[],
383 int expected_bitrate) {
384 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
385 EXPECT_EQ(expected_name, spec->format.name);
386 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700387 }
388
ossu20a4b3f2017-04-27 02:08:52 -0700389 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
390 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700391 }
392
minyue6b825df2016-10-31 04:08:32 -0700393 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
394 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
395 }
396
skvlade0d46372016-04-07 22:59:22 -0700397 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
398 int global_max,
399 int stream_max,
400 bool expected_result,
401 int expected_codec_bitrate) {
402 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800403 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700404
405 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700406 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800407 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700408
409 // Verify that reading back the parameters gives results
410 // consistent with the Set() result.
411 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800412 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700413 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
414 EXPECT_EQ(expected_result ? stream_max : -1,
415 resulting_parameters.encodings[0].max_bitrate_bps);
416
417 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800418 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700419 }
420
stefan13f1a0a2016-11-30 07:22:58 -0800421 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
422 int expected_min_bitrate_bps,
423 const char* start_bitrate_kbps,
424 int expected_start_bitrate_bps,
425 const char* max_bitrate_kbps,
426 int expected_max_bitrate_bps) {
427 EXPECT_TRUE(SetupSendStream());
428 auto& codecs = send_parameters_.codecs;
429 codecs.clear();
430 codecs.push_back(kOpusCodec);
431 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
432 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
433 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100434 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
435 SetSdpBitrateParameters(
436 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
437 expected_min_bitrate_bps),
438 Field(&BitrateConstraints::start_bitrate_bps,
439 expected_start_bitrate_bps),
440 Field(&BitrateConstraints::max_bitrate_bps,
441 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800442
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100443 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100536 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100541 stats.apm_statistics.delay_median_ms = 234;
542 stats.apm_statistics.delay_standard_deviation_ms = 567;
543 stats.apm_statistics.echo_return_loss = 890;
544 stats.apm_statistics.echo_return_loss_enhancement = 1234;
545 stats.apm_statistics.residual_echo_likelihood = 0.432f;
546 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100547 stats.ana_statistics.bitrate_action_counter = 321;
548 stats.ana_statistics.channel_action_counter = 432;
549 stats.ana_statistics.dtx_action_counter = 543;
550 stats.ana_statistics.fec_action_counter = 654;
551 stats.ana_statistics.frame_length_increase_counter = 765;
552 stats.ana_statistics.frame_length_decrease_counter = 876;
553 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700554 stats.typing_noise_detected = true;
555 return stats;
556 }
557 void SetAudioSendStreamStats() {
558 for (auto* s : call_.GetAudioSendStreams()) {
559 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200560 }
solenberg85a04962015-10-27 03:35:21 -0700561 }
solenberg566ef242015-11-06 15:34:49 -0800562 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
563 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700564 const auto stats = GetAudioSendStreamStats();
565 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
566 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
567 EXPECT_EQ(info.packets_sent, stats.packets_sent);
568 EXPECT_EQ(info.packets_lost, stats.packets_lost);
569 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
570 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800571 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700572 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
573 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
574 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
575 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100576 EXPECT_EQ(info.apm_statistics.delay_median_ms,
577 stats.apm_statistics.delay_median_ms);
578 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
579 stats.apm_statistics.delay_standard_deviation_ms);
580 EXPECT_EQ(info.apm_statistics.echo_return_loss,
581 stats.apm_statistics.echo_return_loss);
582 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
583 stats.apm_statistics.echo_return_loss_enhancement);
584 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
585 stats.apm_statistics.residual_echo_likelihood);
586 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
587 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700588 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
589 stats.ana_statistics.bitrate_action_counter);
590 EXPECT_EQ(info.ana_statistics.channel_action_counter,
591 stats.ana_statistics.channel_action_counter);
592 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
593 stats.ana_statistics.dtx_action_counter);
594 EXPECT_EQ(info.ana_statistics.fec_action_counter,
595 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700596 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
597 stats.ana_statistics.frame_length_increase_counter);
598 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
599 stats.ana_statistics.frame_length_decrease_counter);
600 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
601 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800602 EXPECT_EQ(info.typing_noise_detected,
603 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700604 }
605
606 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
607 webrtc::AudioReceiveStream::Stats stats;
608 stats.remote_ssrc = 123;
609 stats.bytes_rcvd = 456;
610 stats.packets_rcvd = 768;
611 stats.packets_lost = 101;
612 stats.fraction_lost = 23.45f;
613 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100614 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700615 stats.ext_seqnum = 678;
616 stats.jitter_ms = 901;
617 stats.jitter_buffer_ms = 234;
618 stats.jitter_buffer_preferred_ms = 567;
619 stats.delay_estimate_ms = 890;
620 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700621 stats.total_samples_received = 5678901;
622 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200623 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200624 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700625 stats.expand_rate = 5.67f;
626 stats.speech_expand_rate = 8.90f;
627 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200628 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700629 stats.accelerate_rate = 4.56f;
630 stats.preemptive_expand_rate = 7.89f;
631 stats.decoding_calls_to_silence_generator = 12;
632 stats.decoding_calls_to_neteq = 345;
633 stats.decoding_normal = 67890;
634 stats.decoding_plc = 1234;
635 stats.decoding_cng = 5678;
636 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700637 stats.decoding_muted_output = 3456;
638 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 return stats;
640 }
641 void SetAudioReceiveStreamStats() {
642 for (auto* s : call_.GetAudioReceiveStreams()) {
643 s->SetStats(GetAudioReceiveStreamStats());
644 }
645 }
646 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700647 const auto stats = GetAudioReceiveStreamStats();
648 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
649 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200650 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
651 stats.packets_rcvd);
652 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
653 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700654 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
655 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800656 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200657 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
658 stats.ext_seqnum);
659 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
660 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
661 stats.jitter_buffer_ms);
662 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700663 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200664 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
665 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700666 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700667 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
668 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200669 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200670 EXPECT_EQ(info.jitter_buffer_delay_seconds,
671 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700672 EXPECT_EQ(info.expand_rate, stats.expand_rate);
673 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
674 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200675 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700676 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
677 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200678 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700679 stats.decoding_calls_to_silence_generator);
680 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
681 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
682 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
683 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
684 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700685 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700686 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200687 }
hbos1acfbd22016-11-17 23:43:29 -0800688 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
689 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
690 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
691 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
692 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
693 codec.ToCodecParameters());
694 }
695 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
696 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
697 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
698 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
699 codec.ToCodecParameters());
700 }
701 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200702
peah8271d042016-11-22 07:24:52 -0800703 bool IsHighPassFilterEnabled() {
704 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
705 }
706
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700708 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700709 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800710 webrtc::test::MockGainControl& apm_gc_;
711 webrtc::test::MockEchoCancellation& apm_ec_;
712 webrtc::test::MockNoiseSuppression& apm_ns_;
713 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200714 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700715 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700716 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200717 cricket::AudioSendParameters send_parameters_;
718 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800719 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700720 webrtc::AudioProcessing::Config apm_config_;
721
stefanba4c0e42016-02-04 04:12:24 -0800722 private:
723 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724};
725
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726// Tests that we can create and destroy a channel.
727TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700728 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729}
730
solenberg31fec402016-05-06 02:13:12 -0700731// Test that we can add a send stream and that it has the correct defaults.
732TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
733 EXPECT_TRUE(SetupChannel());
734 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800735 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
736 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
737 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700738 EXPECT_EQ("", config.rtp.c_name);
739 EXPECT_EQ(0u, config.rtp.extensions.size());
740 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
741 config.send_transport);
742}
743
744// Test that we can add a receive stream and that it has the correct defaults.
745TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
746 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800747 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700748 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800749 GetRecvStreamConfig(kSsrcX);
750 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700751 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
752 EXPECT_FALSE(config.rtp.transport_cc);
753 EXPECT_EQ(0u, config.rtp.extensions.size());
754 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
755 config.rtcp_send_transport);
756 EXPECT_EQ("", config.sync_group);
757}
758
stefanba4c0e42016-02-04 04:12:24 -0800759TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700760 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800761 bool opus_found = false;
762 for (cricket::AudioCodec codec : codecs) {
763 if (codec.name == "opus") {
764 EXPECT_TRUE(HasTransportCc(codec));
765 opus_found = true;
766 }
767 }
768 EXPECT_TRUE(opus_found);
769}
770
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771// Test that we set our inbound codecs properly, including changing PT.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800777 parameters.codecs.push_back(kTelephoneEventCodec1);
778 parameters.codecs.push_back(kTelephoneEventCodec2);
779 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200780 parameters.codecs[2].id = 126;
781 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800782 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700783 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
784 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
785 {{0, {"PCMU", 8000, 1}},
786 {106, {"ISAC", 16000, 1}},
787 {126, {"telephone-event", 8000, 1}},
788 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail to set an unknown inbound codec.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700796 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798}
799
800// Test that we fail if we have duplicate types in the inbound list.
801TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700802 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200803 cricket::AudioRecvParameters parameters;
804 parameters.codecs.push_back(kIsacCodec);
805 parameters.codecs.push_back(kCn16000Codec);
806 parameters.codecs[1].id = kIsacCodec.id;
807 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that we can decode OPUS without stereo parameters.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
816 parameters.codecs.push_back(kOpusCodec);
817 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800818 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700819 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
820 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
821 {{0, {"PCMU", 8000, 1}},
822 {103, {"ISAC", 16000, 1}},
823 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS with stereo = 0.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 parameters.codecs[2].params["stereo"] = "0";
834 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800835 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700836 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
837 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
838 {{0, {"PCMU", 8000, 1}},
839 {103, {"ISAC", 16000, 1}},
840 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can decode OPUS with stereo = 1.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kPcmuCodec);
849 parameters.codecs.push_back(kOpusCodec);
850 parameters.codecs[2].params["stereo"] = "1";
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700853 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
854 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
855 {{0, {"PCMU", 8000, 1}},
856 {103, {"ISAC", 16000, 1}},
857 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that changes to recv codecs are applied to all streams.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800866 parameters.codecs.push_back(kTelephoneEventCodec1);
867 parameters.codecs.push_back(kTelephoneEventCodec2);
868 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200869 parameters.codecs[2].id = 126;
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700871 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
872 EXPECT_TRUE(AddRecvStream(ssrc));
873 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
874 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
875 {{0, {"PCMU", 8000, 1}},
876 {106, {"ISAC", 16000, 1}},
877 {126, {"telephone-event", 8000, 1}},
878 {107, {"telephone-event", 32000, 1}}})));
879 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800886 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
solenberg2100c0b2017-03-01 11:29:29 -0800889 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200890 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800891 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894// Test that we can apply the same set of codecs again while playing.
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
899 parameters.codecs.push_back(kCn16000Codec);
900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700901 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
deadbeefcb383672017-04-26 16:28:42 -0700904 // Remapping a payload type to a different codec should fail.
905 parameters.codecs[0] = kOpusCodec;
906 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800908 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can add a codec while playing.
912TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kCn16000Codec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700918 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 parameters.codecs.push_back(kOpusCodec);
921 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800922 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
deadbeefcb383672017-04-26 16:28:42 -0700925// Test that we accept adding the same codec with a different payload type.
926// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
927TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
928 EXPECT_TRUE(SetupRecvStream());
929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932
933 ++parameters.codecs[0].id;
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
935}
936
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 // Test that when autobw is enabled, bitrate is kept as the default
941 // value. autobw is enabled for the following tests because the target
942 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
947 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700948 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
ossu20a4b3f2017-04-27 02:08:52 -0700950 // opus, default bitrate == 32000 in mono.
951 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
959 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700960 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
964 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
965 // Rates above the max (510000) should be capped.
966 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971
972 // Test that we can only set a maximum bitrate for a fixed-rate codec
973 // if it's bigger than the fixed rate.
974
975 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983}
984
985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 const int kDesiredBitrate = 128000;
988 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700989 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200990 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700991 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
993 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800994 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000995
solenberg2100c0b2017-03-01 11:29:29 -0800996 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000997}
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999// Test that bitrate cannot be set for CBR codecs.
1000// Bitrate is ignored if it is higher than the fixed bitrate.
1001// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008
1009 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001010 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001012
1013 send_parameters_.max_bandwidth_bps = 128;
1014 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016}
1017
skvlade0d46372016-04-07 22:59:22 -07001018// Test that the per-stream bitrate limit and the global
1019// bitrate limit both apply.
1020TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1021 EXPECT_TRUE(SetupSendStream());
1022
ossu20a4b3f2017-04-27 02:08:52 -07001023 // opus, default bitrate == 32000.
1024 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001025 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1028
1029 // CBR codecs allow both maximums to exceed the bitrate.
1030 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1031 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1034
1035 // CBR codecs don't allow per stream maximums to be too low.
1036 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1037 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1038}
1039
1040// Test that an attempt to set RtpParameters for a stream that does not exist
1041// fails.
1042TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1043 EXPECT_TRUE(SetupChannel());
1044 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001045 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001046 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001047
1048 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001049 EXPECT_FALSE(
1050 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001051}
1052
1053TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001054 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001055 // This test verifies that setting RtpParameters succeeds only if
1056 // the structure contains exactly one encoding.
1057 // TODO(skvlad): Update this test when we start supporting setting parameters
1058 // for each encoding individually.
1059
1060 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001061 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001062 // Two or more encodings should result in failure.
1063 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001064 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001065 // Zero encodings should also fail.
1066 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001067 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001068}
1069
1070// Changing the SSRC through RtpParameters is not allowed.
1071TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1072 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001074 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001076}
1077
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001078// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001079// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1081 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001082 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001084 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001085 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086 ASSERT_EQ(1u, parameters.encodings.size());
1087 ASSERT_TRUE(parameters.encodings[0].active);
1088 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001089 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091
1092 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001093 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001095 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001096 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001097 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098}
1099
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001100// Test that SetRtpSendParameters configures the correct encoding channel for
1101// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001102TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1103 SetupForMultiSendStream();
1104 // Create send streams.
1105 for (uint32_t ssrc : kSsrcs4) {
1106 EXPECT_TRUE(
1107 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1108 }
1109 // Configure one stream to be limited by the stream config, another to be
1110 // limited by the global max, and the third one with no per-stream limit
1111 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001112 SetGlobalMaxBitrate(kOpusCodec, 32000);
1113 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1114 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001115 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1116
ossu20a4b3f2017-04-27 02:08:52 -07001117 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1118 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1119 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001120
1121 // Remove the global cap; the streams should switch to their respective
1122 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001123 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001124 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1125 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1126 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001127}
1128
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001129// Test that GetRtpSendParameters returns the currently configured codecs.
1130TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131 EXPECT_TRUE(SetupSendStream());
1132 cricket::AudioSendParameters parameters;
1133 parameters.codecs.push_back(kIsacCodec);
1134 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001135 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001136
solenberg2100c0b2017-03-01 11:29:29 -08001137 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1140 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001141}
1142
Florent Castellidacec712018-05-24 16:24:21 +02001143// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1144TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1145 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1146 params.cname = "rtcpcname";
1147 EXPECT_TRUE(SetupSendStream(params));
1148
1149 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1150 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1151}
1152
deadbeefcb443432016-12-12 11:12:36 -08001153// Test that GetRtpSendParameters returns an SSRC.
1154TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1155 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001156 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001157 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001158 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001159}
1160
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001161// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001162TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001163 EXPECT_TRUE(SetupSendStream());
1164 cricket::AudioSendParameters parameters;
1165 parameters.codecs.push_back(kIsacCodec);
1166 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001167 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001168
solenberg2100c0b2017-03-01 11:29:29 -08001169 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170
1171 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001172 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001173
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001174 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001175 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1176 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001177}
1178
minyuececec102017-03-27 13:04:25 -07001179// Test that max_bitrate_bps in send stream config gets updated correctly when
1180// SetRtpSendParameters is called.
1181TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1182 webrtc::test::ScopedFieldTrials override_field_trials(
1183 "WebRTC-Audio-SendSideBwe/Enabled/");
1184 EXPECT_TRUE(SetupSendStream());
1185 cricket::AudioSendParameters send_parameters;
1186 send_parameters.codecs.push_back(kOpusCodec);
1187 SetSendParameters(send_parameters);
1188
1189 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1190 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1191 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1192
1193 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001194 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001195 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001196
1197 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1198 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1199}
1200
Seth Hampson24722b32017-12-22 09:36:42 -08001201// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1202// a value <= 0, setting the parameters returns false.
1203TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1204 EXPECT_TRUE(SetupSendStream());
1205 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1206 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1207 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1208 rtp_parameters.encodings[0].bitrate_priority);
1209
1210 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001211 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001212 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001213 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001214}
1215
1216// Test that the bitrate_priority in the send stream config gets updated when
1217// SetRtpSendParameters is set for the VoiceMediaChannel.
1218TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1219 EXPECT_TRUE(SetupSendStream());
1220 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1221
1222 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1223 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1224 rtp_parameters.encodings[0].bitrate_priority);
1225 double new_bitrate_priority = 2.0;
1226 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001227 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001228
1229 // The priority should get set for both the audio channel's rtp parameters
1230 // and the audio send stream's audio config.
1231 EXPECT_EQ(
1232 new_bitrate_priority,
1233 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1234 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1235}
1236
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001237// Test that GetRtpReceiveParameters returns the currently configured codecs.
1238TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1239 EXPECT_TRUE(SetupRecvStream());
1240 cricket::AudioRecvParameters parameters;
1241 parameters.codecs.push_back(kIsacCodec);
1242 parameters.codecs.push_back(kPcmuCodec);
1243 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1244
1245 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001246 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001247 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1248 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1249 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1250}
1251
deadbeefcb443432016-12-12 11:12:36 -08001252// Test that GetRtpReceiveParameters returns an SSRC.
1253TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1254 EXPECT_TRUE(SetupRecvStream());
1255 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001256 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001257 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001258 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001259}
1260
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001261// Test that if we set/get parameters multiple times, we get the same results.
1262TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1263 EXPECT_TRUE(SetupRecvStream());
1264 cricket::AudioRecvParameters parameters;
1265 parameters.codecs.push_back(kIsacCodec);
1266 parameters.codecs.push_back(kPcmuCodec);
1267 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1268
1269 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001270 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001271
1272 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001273 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001274
1275 // ... And this shouldn't change the params returned by
1276 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001277 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1278 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001279}
1280
deadbeef3bc15102017-04-20 19:25:07 -07001281// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1282// aren't signaled. It should return an empty "RtpEncodingParameters" when
1283// configured to receive an unsignaled stream and no packets have been received
1284// yet, and start returning the SSRC once a packet has been received.
1285TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1286 ASSERT_TRUE(SetupChannel());
1287 // Call necessary methods to configure receiving a default stream as
1288 // soon as it arrives.
1289 cricket::AudioRecvParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
1292 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1293
1294 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1295 // stream. Should return nothing.
1296 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1297
1298 // Set a sink for an unsignaled stream.
1299 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1300 // Value of "0" means "unsignaled stream".
1301 channel_->SetRawAudioSink(0, std::move(fake_sink));
1302
1303 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1304 // in this method means "unsignaled stream".
1305 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1306 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1307 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1308
1309 // Receive PCMU packet (SSRC=1).
1310 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1311
1312 // The |ssrc| member should still be unset.
1313 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1314 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1315 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1316}
1317
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001318// Test that we apply codecs properly.
1319TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001320 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001321 cricket::AudioSendParameters parameters;
1322 parameters.codecs.push_back(kIsacCodec);
1323 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001324 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001325 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001326 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001327 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001328 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1329 EXPECT_EQ(96, send_codec_spec.payload_type);
1330 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1331 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1332 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001333 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001334 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
ossu20a4b3f2017-04-27 02:08:52 -07001337// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1338// AudioSendStream.
1339TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001340 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001341 cricket::AudioSendParameters parameters;
1342 parameters.codecs.push_back(kIsacCodec);
1343 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001344 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001345 parameters.codecs[0].id = 96;
1346 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001347 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001348 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001349 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001350 // Calling SetSendCodec again with same codec which is already set.
1351 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001353 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001354}
1355
ossu20a4b3f2017-04-27 02:08:52 -07001356// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1357// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001358
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001359// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001360TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001361 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 cricket::AudioSendParameters parameters;
1363 parameters.codecs.push_back(kOpusCodec);
1364 parameters.codecs[0].bitrate = 0;
1365 parameters.codecs[0].clockrate = 50000;
1366 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001367}
1368
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001369// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].bitrate = 0;
1375 parameters.codecs[0].channels = 0;
1376 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377}
1378
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001379// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001380TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001381 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 0;
1385 parameters.codecs[0].channels = 0;
1386 parameters.codecs[0].params["stereo"] = "1";
1387 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388}
1389
1390// Test that if channel is 1 for opus and there's no stereo, we fail.
1391TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001392 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 cricket::AudioSendParameters parameters;
1394 parameters.codecs.push_back(kOpusCodec);
1395 parameters.codecs[0].bitrate = 0;
1396 parameters.codecs[0].channels = 1;
1397 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
1400// Test that if channel is 1 for opus and stereo=0, we fail.
1401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].bitrate = 0;
1406 parameters.codecs[0].channels = 1;
1407 parameters.codecs[0].params["stereo"] = "0";
1408 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409}
1410
1411// Test that if channel is 1 for opus and stereo=1, we fail.
1412TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001413 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 cricket::AudioSendParameters parameters;
1415 parameters.codecs.push_back(kOpusCodec);
1416 parameters.codecs[0].bitrate = 0;
1417 parameters.codecs[0].channels = 1;
1418 parameters.codecs[0].params["stereo"] = "1";
1419 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001420}
1421
ossu20a4b3f2017-04-27 02:08:52 -07001422// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kOpusCodec);
1427 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001428 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001429 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001430}
1431
ossu20a4b3f2017-04-27 02:08:52 -07001432// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001434 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 cricket::AudioSendParameters parameters;
1436 parameters.codecs.push_back(kOpusCodec);
1437 parameters.codecs[0].bitrate = 0;
1438 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441}
1442
ossu20a4b3f2017-04-27 02:08:52 -07001443// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001449 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001451 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001452 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001453
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001455 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001456 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001457}
1458
ossu20a4b3f2017-04-27 02:08:52 -07001459// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001461 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 cricket::AudioSendParameters parameters;
1463 parameters.codecs.push_back(kOpusCodec);
1464 parameters.codecs[0].bitrate = 0;
1465 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001466 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001467 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468}
1469
ossu20a4b3f2017-04-27 02:08:52 -07001470// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001471TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001472 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 cricket::AudioSendParameters parameters;
1474 parameters.codecs.push_back(kOpusCodec);
1475 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001476 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001478 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001479 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001480
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001483 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484}
1485
ossu20a4b3f2017-04-27 02:08:52 -07001486// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001488 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001489 cricket::AudioSendParameters parameters;
1490 parameters.codecs.push_back(kOpusCodec);
1491 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001492 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001493 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1494 EXPECT_EQ(111, spec.payload_type);
1495 EXPECT_EQ(96000, spec.target_bitrate_bps);
1496 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001497 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001498 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499}
1500
ossu20a4b3f2017-04-27 02:08:52 -07001501// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001502TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001503 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001504 cricket::AudioSendParameters parameters;
1505 parameters.codecs.push_back(kOpusCodec);
1506 parameters.codecs[0].bitrate = 30000;
1507 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001508 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001509 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001510}
1511
ossu20a4b3f2017-04-27 02:08:52 -07001512// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001514 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001515 cricket::AudioSendParameters parameters;
1516 parameters.codecs.push_back(kOpusCodec);
1517 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001518 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001519 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001520}
1521
ossu20a4b3f2017-04-27 02:08:52 -07001522// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001523TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001524 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001525 cricket::AudioSendParameters parameters;
1526 parameters.codecs.push_back(kOpusCodec);
1527 parameters.codecs[0].bitrate = 30000;
1528 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001529 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001530 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001531}
1532
stefan13f1a0a2016-11-30 07:22:58 -08001533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1534 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1535 200000);
1536}
1537
1538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1539 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1540}
1541
1542TEST_F(WebRtcVoiceEngineTestFake,
1543 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1544 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1545}
1546
1547TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1548 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1549}
1550
1551TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001552 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001553 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1554 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001555 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001556 // Setting max bitrate should keep previous min bitrate
1557 // Setting max bitrate should not reset start bitrate.
1558 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1559 SetSdpBitrateParameters(
1560 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1561 Field(&BitrateConstraints::start_bitrate_bps, -1),
1562 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001563 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001564}
1565
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001566// Test that we can enable NACK with opus as caller.
1567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001568 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::AudioSendParameters parameters;
1570 parameters.codecs.push_back(kOpusCodec);
1571 parameters.codecs[0].AddFeedbackParam(
1572 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1573 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001575 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001576 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001579// Test that we can enable NACK with opus as callee.
1580TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001581 EXPECT_TRUE(SetupRecvStream());
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, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001588 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001589 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001591
1592 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001593 cricket::StreamParams::CreateLegacy(kSsrcX)));
1594 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001595}
1596
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597// Test that we can enable NACK on receive streams.
1598TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001600 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001601 cricket::AudioSendParameters parameters;
1602 parameters.codecs.push_back(kOpusCodec);
1603 parameters.codecs[0].AddFeedbackParam(
1604 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1605 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001606 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1607 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001608 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1610 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
1613// Test that we can disable NACK.
1614TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001615 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kOpusCodec);
1618 parameters.codecs[0].AddFeedbackParam(
1619 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1620 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623
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);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001628}
1629
1630// Test that we can disable NACK on receive streams.
1631TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001632 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001633 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001634 cricket::AudioSendParameters parameters;
1635 parameters.codecs.push_back(kOpusCodec);
1636 parameters.codecs[0].AddFeedbackParam(
1637 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1638 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001639 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001640 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1641 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001643 parameters.codecs.clear();
1644 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001645 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001646 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1647 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648}
1649
1650// Test that NACK is enabled on a new receive stream.
1651TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001652 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 cricket::AudioSendParameters parameters;
1654 parameters.codecs.push_back(kIsacCodec);
1655 parameters.codecs.push_back(kCn16000Codec);
1656 parameters.codecs[0].AddFeedbackParam(
1657 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1658 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661
solenberg2100c0b2017-03-01 11:29:29 -08001662 EXPECT_TRUE(AddRecvStream(kSsrcY));
1663 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1664 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1665 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666}
1667
stefanba4c0e42016-02-04 04:12:24 -08001668TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001670 cricket::AudioSendParameters send_parameters;
1671 send_parameters.codecs.push_back(kOpusCodec);
1672 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001674
1675 cricket::AudioRecvParameters recv_parameters;
1676 recv_parameters.codecs.push_back(kIsacCodec);
1677 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_TRUE(AddRecvStream(kSsrcX));
1679 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001680 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001681 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001682
ossudedfd282016-06-14 07:12:39 -07001683 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001684 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001685 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001686 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001687 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001688}
1689
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001690// Test that we can switch back and forth between Opus and ISAC with CN.
1691TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001692 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001693
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 cricket::AudioSendParameters opus_parameters;
1695 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001697 {
ossu20a4b3f2017-04-27 02:08:52 -07001698 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1699 EXPECT_EQ(111, spec.payload_type);
1700 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001701 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 cricket::AudioSendParameters isac_parameters;
1704 isac_parameters.codecs.push_back(kIsacCodec);
1705 isac_parameters.codecs.push_back(kCn16000Codec);
1706 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001708 {
ossu20a4b3f2017-04-27 02:08:52 -07001709 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1710 EXPECT_EQ(103, spec.payload_type);
1711 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001712 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001713
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001715 {
ossu20a4b3f2017-04-27 02:08:52 -07001716 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1717 EXPECT_EQ(111, spec.payload_type);
1718 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720}
1721
1722// Test that we handle various ways of specifying bitrate.
1723TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001725 cricket::AudioSendParameters parameters;
1726 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001728 {
ossu20a4b3f2017-04-27 02:08:52 -07001729 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1730 EXPECT_EQ(103, spec.payload_type);
1731 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1732 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001736 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001737 {
ossu20a4b3f2017-04-27 02:08:52 -07001738 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1739 EXPECT_EQ(103, spec.payload_type);
1740 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1741 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001742 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001745 {
ossu20a4b3f2017-04-27 02:08:52 -07001746 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1747 EXPECT_EQ(103, spec.payload_type);
1748 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1749 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001750 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001751
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001752 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
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(0, spec.payload_type);
1757 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1758 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001759 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001761 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(0, spec.payload_type);
1766 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1767 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001768 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001769
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001770 parameters.codecs[0] = kOpusCodec;
1771 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001772 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001773 {
ossu20a4b3f2017-04-27 02:08:52 -07001774 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1775 EXPECT_EQ(111, spec.payload_type);
1776 EXPECT_STREQ("opus", spec.format.name.c_str());
1777 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001778 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779}
1780
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001781// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001782TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001783 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 cricket::AudioSendParameters parameters;
1785 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001786}
1787
1788// Test that we can set send codecs even with telephone-event codec as the first
1789// one on the list.
1790TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001791 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001792 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001793 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001794 parameters.codecs.push_back(kIsacCodec);
1795 parameters.codecs.push_back(kPcmuCodec);
1796 parameters.codecs[0].id = 98; // DTMF
1797 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001799 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1800 EXPECT_EQ(96, spec.payload_type);
1801 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001802 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001803 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001804}
1805
Harald Alvestranda1f66612018-02-21 11:24:23 +01001806// Test that CanInsertDtmf() is governed by the send flag
1807TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1808 EXPECT_TRUE(SetupSendStream());
1809 cricket::AudioSendParameters parameters;
1810 parameters.codecs.push_back(kTelephoneEventCodec1);
1811 parameters.codecs.push_back(kPcmuCodec);
1812 parameters.codecs[0].id = 98; // DTMF
1813 parameters.codecs[1].id = 96;
1814 SetSendParameters(parameters);
1815 EXPECT_FALSE(channel_->CanInsertDtmf());
1816 SetSend(true);
1817 EXPECT_TRUE(channel_->CanInsertDtmf());
1818 SetSend(false);
1819 EXPECT_FALSE(channel_->CanInsertDtmf());
1820}
1821
solenberg31642aa2016-03-14 08:00:37 -07001822// Test that payload type range is limited for telephone-event codec.
1823TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001824 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001825 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001826 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001827 parameters.codecs.push_back(kIsacCodec);
1828 parameters.codecs[0].id = 0; // DTMF
1829 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001831 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001832 EXPECT_TRUE(channel_->CanInsertDtmf());
1833 parameters.codecs[0].id = 128; // DTMF
1834 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1835 EXPECT_FALSE(channel_->CanInsertDtmf());
1836 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001837 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001838 EXPECT_TRUE(channel_->CanInsertDtmf());
1839 parameters.codecs[0].id = -1; // DTMF
1840 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1841 EXPECT_FALSE(channel_->CanInsertDtmf());
1842}
1843
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001844// Test that we can set send codecs even with CN codec as the first
1845// one on the list.
1846TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001847 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 cricket::AudioSendParameters parameters;
1849 parameters.codecs.push_back(kCn16000Codec);
1850 parameters.codecs.push_back(kIsacCodec);
1851 parameters.codecs.push_back(kPcmuCodec);
1852 parameters.codecs[0].id = 98; // wideband CN
1853 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001854 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001855 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1856 EXPECT_EQ(96, send_codec_spec.payload_type);
1857 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001858 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859}
1860
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001861// Test that we set VAD and DTMF types correctly as caller.
1862TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001863 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001864 cricket::AudioSendParameters parameters;
1865 parameters.codecs.push_back(kIsacCodec);
1866 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001867 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001868 parameters.codecs.push_back(kCn16000Codec);
1869 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001870 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 parameters.codecs[0].id = 96;
1872 parameters.codecs[2].id = 97; // wideband CN
1873 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001875 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1876 EXPECT_EQ(96, send_codec_spec.payload_type);
1877 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001878 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001879 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001880 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001881 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882}
1883
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001884// Test that we set VAD and DTMF types correctly as callee.
1885TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001886 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 cricket::AudioSendParameters parameters;
1888 parameters.codecs.push_back(kIsacCodec);
1889 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001890 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 parameters.codecs.push_back(kCn16000Codec);
1892 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001893 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001894 parameters.codecs[0].id = 96;
1895 parameters.codecs[2].id = 97; // wideband CN
1896 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001898 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001899 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001900
ossu20a4b3f2017-04-27 02:08:52 -07001901 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1902 EXPECT_EQ(96, send_codec_spec.payload_type);
1903 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001904 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001906 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001907 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001908}
1909
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910// Test that we only apply VAD if we have a CN codec that matches the
1911// send codec clockrate.
1912TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001913 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001915 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001916 parameters.codecs.push_back(kIsacCodec);
1917 parameters.codecs.push_back(kCn16000Codec);
1918 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001919 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001920 {
ossu20a4b3f2017-04-27 02:08:52 -07001921 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1922 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001923 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001924 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001925 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001926 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001927 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001928 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001929 {
ossu20a4b3f2017-04-27 02:08:52 -07001930 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1931 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001932 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001933 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001934 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001935 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001936 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001937 {
ossu20a4b3f2017-04-27 02:08:52 -07001938 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1939 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001940 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001941 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001942 }
Brave Yao5225dd82015-03-26 07:39:19 +08001943 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001944 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001945 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001946 {
ossu20a4b3f2017-04-27 02:08:52 -07001947 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1948 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001949 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001950 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001951}
1952
1953// Test that we perform case-insensitive matching of codec names.
1954TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001955 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001956 cricket::AudioSendParameters parameters;
1957 parameters.codecs.push_back(kIsacCodec);
1958 parameters.codecs.push_back(kPcmuCodec);
1959 parameters.codecs.push_back(kCn16000Codec);
1960 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001961 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001962 parameters.codecs[0].name = "iSaC";
1963 parameters.codecs[0].id = 96;
1964 parameters.codecs[2].id = 97; // wideband CN
1965 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001966 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001967 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1968 EXPECT_EQ(96, send_codec_spec.payload_type);
1969 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001970 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001971 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001972 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001973 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001974}
1975
stefanba4c0e42016-02-04 04:12:24 -08001976class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1977 public:
1978 WebRtcVoiceEngineWithSendSideBweTest()
1979 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1980};
1981
1982TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1983 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001984 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001985 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001986 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1987 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1988 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001989 extension.id);
1990 return;
1991 }
1992 }
1993 FAIL() << "Transport sequence number extension not in header-extension list.";
1994}
1995
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001996// Test support for audio level header extension.
1997TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001998 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001999}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002000TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002001 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002002}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002003
solenbergd4adce42016-11-17 06:26:52 -08002004// Test support for transport sequence number header extension.
2005TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2006 TestSetSendRtpHeaderExtensions(
2007 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002008}
solenbergd4adce42016-11-17 06:26:52 -08002009TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2010 TestSetRecvRtpHeaderExtensions(
2011 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012}
2013
solenberg1ac56142015-10-13 03:58:19 -07002014// Test that we can create a channel and start sending on it.
2015TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002016 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002017 SetSendParameters(send_parameters_);
2018 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002019 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002020 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002021 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002022}
2023
2024// Test that a channel will send if and only if it has a source and is enabled
2025// for sending.
2026TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002027 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002028 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002029 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002030 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002031 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2032 SetAudioSend(kSsrcX, true, &fake_source_);
2033 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2034 SetAudioSend(kSsrcX, true, nullptr);
2035 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002036}
2037
solenberg94218532016-06-16 10:53:22 -07002038// Test that a channel is muted/unmuted.
2039TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2040 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002041 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002042 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2043 SetAudioSend(kSsrcX, true, nullptr);
2044 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2045 SetAudioSend(kSsrcX, false, nullptr);
2046 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002047}
2048
solenberg6d6e7c52016-04-13 09:07:30 -07002049// Test that SetSendParameters() does not alter a stream's send state.
2050TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2051 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002052 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002053
2054 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002055 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002056 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002057
2058 // Changing RTP header extensions will recreate the AudioSendStream.
2059 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002060 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002061 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002062 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002063
2064 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002065 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002066 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002067
2068 // Changing RTP header extensions will recreate the AudioSendStream.
2069 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002070 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002071 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002072}
2073
solenberg1ac56142015-10-13 03:58:19 -07002074// Test that we can create a channel and start playing out on it.
2075TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002076 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002077 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002078 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002080 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002082}
2083
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002084// Test that we can add and remove send streams.
2085TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2086 SetupForMultiSendStream();
2087
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002089 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002090
solenbergc96df772015-10-21 13:01:53 -07002091 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002092 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002093 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002094 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002095 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002096 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 }
tfarina5237aaf2015-11-10 23:44:30 -08002098 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099
solenbergc96df772015-10-21 13:01:53 -07002100 // Delete the send streams.
2101 for (uint32_t ssrc : kSsrcs4) {
2102 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002103 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002104 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105 }
solenbergc96df772015-10-21 13:01:53 -07002106 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107}
2108
2109// Test SetSendCodecs correctly configure the codecs in all send streams.
2110TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2111 SetupForMultiSendStream();
2112
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002114 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002116 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117 }
2118
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002119 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002121 parameters.codecs.push_back(kIsacCodec);
2122 parameters.codecs.push_back(kCn16000Codec);
2123 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002124 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125
2126 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002127 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002128 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2129 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002130 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2131 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002132 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002133 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 }
2135
minyue7a973442016-10-20 03:27:12 -07002136 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002137 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002138 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002139 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002140 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2141 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002142 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2143 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002144 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002145 }
2146}
2147
2148// Test we can SetSend on all send streams correctly.
2149TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2150 SetupForMultiSendStream();
2151
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002152 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002153 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002155 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002156 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002157 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 }
2159
2160 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002161 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002162 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002164 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 }
2166
2167 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002168 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002169 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002170 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002171 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002172 }
2173}
2174
2175// Test we can set the correct statistics on all send streams.
2176TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2177 SetupForMultiSendStream();
2178
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002181 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002182 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
solenberg85a04962015-10-27 03:35:21 -07002184
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002185 // Create a receive stream to check that none of the send streams end up in
2186 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002188
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002189 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002190 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002191 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002192 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193
solenberg85a04962015-10-27 03:35:21 -07002194 // Check stats for the added streams.
2195 {
2196 cricket::VoiceMediaInfo info;
2197 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002198
solenberg85a04962015-10-27 03:35:21 -07002199 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002200 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002201 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002202 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002203 }
hbos1acfbd22016-11-17 23:43:29 -08002204 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002205
2206 // We have added one receive stream. We should see empty stats.
2207 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002208 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002209 }
solenberg1ac56142015-10-13 03:58:19 -07002210
solenberg2100c0b2017-03-01 11:29:29 -08002211 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002212 {
2213 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002215 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002216 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002217 EXPECT_EQ(0u, info.receivers.size());
2218 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002219
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002220 // Deliver a new packet - a default receive stream should be created and we
2221 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002222 {
2223 cricket::VoiceMediaInfo info;
2224 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2225 SetAudioReceiveStreamStats();
2226 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002227 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002228 EXPECT_EQ(1u, info.receivers.size());
2229 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002230 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002231 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002232}
2233
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002234// Test that we can add and remove receive streams, and do proper send/playout.
2235// We can receive on multiple streams while sending one stream.
2236TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002237 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002238
solenberg1ac56142015-10-13 03:58:19 -07002239 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002240 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002241 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002242
solenberg1ac56142015-10-13 03:58:19 -07002243 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002244 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002245 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002246 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002247
solenberg1ac56142015-10-13 03:58:19 -07002248 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002249 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250
2251 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002252 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2253 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2254 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002255
2256 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002257 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002258 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002259
2260 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002261 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2263 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002264
aleloi84ef6152016-08-04 05:28:21 -07002265 // Restart playout and make sure recv streams are played out.
2266 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002267 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2268 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002269
aleloi84ef6152016-08-04 05:28:21 -07002270 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002271 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2272 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002273}
2274
wu@webrtc.org97077a32013-10-25 21:18:33 +00002275TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002276 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002277 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2278 .Times(1)
2279 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002280 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2281 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002282 send_parameters_.options.tx_agc_target_dbov = 3;
2283 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2284 send_parameters_.options.tx_agc_limiter = true;
2285 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002286 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2287 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2288 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002289 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002290}
2291
minyue6b825df2016-10-31 04:08:32 -07002292TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2293 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002294 send_parameters_.options.audio_network_adaptor = true;
2295 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002296 SetSendParameters(send_parameters_);
2297 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002298 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002299}
2300
2301TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2302 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002303 send_parameters_.options.audio_network_adaptor = true;
2304 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002305 SetSendParameters(send_parameters_);
2306 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002307 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002308 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002309 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002310 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002311 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002312}
2313
2314TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2315 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002316 send_parameters_.options.audio_network_adaptor = true;
2317 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002318 SetSendParameters(send_parameters_);
2319 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002320 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002321 const int initial_num = call_.GetNumCreatedSendStreams();
2322 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002323 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002324 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2325 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002326 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002327 // AudioSendStream not expected to be recreated.
2328 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2329 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002330 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002331}
2332
michaelt6672b262017-01-11 10:17:59 -08002333class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2334 : public WebRtcVoiceEngineTestFake {
2335 public:
2336 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2337 : WebRtcVoiceEngineTestFake(
2338 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2339 "Enabled/") {}
2340};
2341
2342TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2343 EXPECT_TRUE(SetupSendStream());
2344 cricket::AudioSendParameters parameters;
2345 parameters.codecs.push_back(kOpusCodec);
2346 SetSendParameters(parameters);
2347 const int initial_num = call_.GetNumCreatedSendStreams();
2348 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2349
2350 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2351 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002352 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2353 constexpr int kMinOverheadBps =
2354 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002355
2356 constexpr int kOpusMinBitrateBps = 6000;
2357 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002358 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002359 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002360 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002361 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002362
Oskar Sundbom78807582017-11-16 11:09:55 +01002363 parameters.options.audio_network_adaptor = true;
2364 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002365 SetSendParameters(parameters);
2366
ossu11bfc532017-02-16 05:37:06 -08002367 constexpr int kMinOverheadWithAnaBps =
2368 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002369
2370 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002371 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002372
minyuececec102017-03-27 13:04:25 -07002373 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002374 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002375}
2376
minyuececec102017-03-27 13:04:25 -07002377// This test is similar to
2378// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2379// additional field trial.
2380TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2381 SetRtpSendParameterUpdatesMaxBitrate) {
2382 EXPECT_TRUE(SetupSendStream());
2383 cricket::AudioSendParameters send_parameters;
2384 send_parameters.codecs.push_back(kOpusCodec);
2385 SetSendParameters(send_parameters);
2386
2387 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2388 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2389 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2390
2391 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002392 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002393 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002394
2395 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2396#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2397 constexpr int kMinOverhead = 3333;
2398#else
2399 constexpr int kMinOverhead = 6666;
2400#endif
2401 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2402}
2403
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002404// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002405// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002406TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002407 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002408 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409}
2410
2411TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2412 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002413 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002414 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002415 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002416 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002417 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002418 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002419 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420
solenberg85a04962015-10-27 03:35:21 -07002421 // Check stats for the added streams.
2422 {
2423 cricket::VoiceMediaInfo info;
2424 EXPECT_EQ(true, channel_->GetStats(&info));
2425
2426 // We have added one send stream. We should see the stats we've set.
2427 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002428 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002429 // We have added one receive stream. We should see empty stats.
2430 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002431 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002432 }
solenberg1ac56142015-10-13 03:58:19 -07002433
solenberg566ef242015-11-06 15:34:49 -08002434 // Start sending - this affects some reported stats.
2435 {
2436 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002437 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002438 EXPECT_EQ(true, channel_->GetStats(&info));
2439 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002440 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002441 }
2442
solenberg2100c0b2017-03-01 11:29:29 -08002443 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002444 {
2445 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002446 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002447 EXPECT_EQ(true, channel_->GetStats(&info));
2448 EXPECT_EQ(1u, info.senders.size());
2449 EXPECT_EQ(0u, info.receivers.size());
2450 }
solenberg1ac56142015-10-13 03:58:19 -07002451
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002452 // Deliver a new packet - a default receive stream should be created and we
2453 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002454 {
2455 cricket::VoiceMediaInfo info;
2456 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2457 SetAudioReceiveStreamStats();
2458 EXPECT_EQ(true, channel_->GetStats(&info));
2459 EXPECT_EQ(1u, info.senders.size());
2460 EXPECT_EQ(1u, info.receivers.size());
2461 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002462 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002463 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464}
2465
2466// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002467// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002468TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002469 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002470 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2471 EXPECT_TRUE(AddRecvStream(kSsrcY));
2472 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473}
2474
2475// Test that the local SSRC is the same on sending and receiving channels if the
2476// receive channel is created before the send channel.
2477TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002478 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002479 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002481 cricket::StreamParams::CreateLegacy(kSsrcX)));
2482 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2483 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484}
2485
2486// Test that we can properly receive packets.
2487TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002489 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002491
2492 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2493 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494}
2495
2496// Test that we can properly receive packets on multiple streams.
2497TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002498 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002499 const uint32_t ssrc1 = 1;
2500 const uint32_t ssrc2 = 2;
2501 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002502 EXPECT_TRUE(AddRecvStream(ssrc1));
2503 EXPECT_TRUE(AddRecvStream(ssrc2));
2504 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002506 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002507 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002509 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510 }
mflodman3d7db262016-04-29 00:57:13 -07002511
2512 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2513 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2514 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2515
2516 EXPECT_EQ(s1.received_packets(), 0);
2517 EXPECT_EQ(s2.received_packets(), 0);
2518 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002519
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002521 EXPECT_EQ(s1.received_packets(), 0);
2522 EXPECT_EQ(s2.received_packets(), 0);
2523 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002524
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002525 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002526 EXPECT_EQ(s1.received_packets(), 1);
2527 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2528 EXPECT_EQ(s2.received_packets(), 0);
2529 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002530
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002532 EXPECT_EQ(s1.received_packets(), 1);
2533 EXPECT_EQ(s2.received_packets(), 1);
2534 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2535 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002536
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002537 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002538 EXPECT_EQ(s1.received_packets(), 1);
2539 EXPECT_EQ(s2.received_packets(), 1);
2540 EXPECT_EQ(s3.received_packets(), 1);
2541 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002542
mflodman3d7db262016-04-29 00:57:13 -07002543 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2544 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2545 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546}
2547
solenberg2100c0b2017-03-01 11:29:29 -08002548// Test that receiving on an unsignaled stream works (a stream is created).
2549TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002550 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002551 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002552
solenberg7e63ef02015-11-20 00:19:43 -08002553 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002554
Mirko Bonadeif859e552018-05-30 15:31:29 +02002555 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002556 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2557 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002558}
2559
Seth Hampson5897a6e2018-04-03 11:16:33 -07002560// Tests that when we add a stream without SSRCs, but contains a stream_id
2561// that it is stored and its stream id is later used when the first packet
2562// arrives to properly create a receive stream with a sync label.
2563TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2564 const char kSyncLabel[] = "sync_label";
2565 EXPECT_TRUE(SetupChannel());
2566 cricket::StreamParams unsignaled_stream;
2567 unsignaled_stream.set_stream_ids({kSyncLabel});
2568 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2569 // The stream shouldn't have been created at this point because it doesn't
2570 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002571 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002572
2573 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2574
Mirko Bonadeif859e552018-05-30 15:31:29 +02002575 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002576 EXPECT_TRUE(
2577 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2578 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2579
2580 // Removing the unsignaled stream clears the cached parameters. If a new
2581 // default unsignaled receive stream is created it will not have a sync group.
2582 channel_->RemoveRecvStream(0);
2583 channel_->RemoveRecvStream(kSsrc1);
2584
2585 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2586
Mirko Bonadeif859e552018-05-30 15:31:29 +02002587 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002588 EXPECT_TRUE(
2589 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2590 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2591}
2592
solenberg2100c0b2017-03-01 11:29:29 -08002593// Test that receiving N unsignaled stream works (streams will be created), and
2594// that packets are forwarded to them all.
2595TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002596 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002597 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002598 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2599
solenberg2100c0b2017-03-01 11:29:29 -08002600 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002601 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002602 rtc::SetBE32(&packet[8], ssrc);
2603 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002604
solenberg2100c0b2017-03-01 11:29:29 -08002605 // Verify we have one new stream for each loop iteration.
2606 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002607 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2608 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002609 }
mflodman3d7db262016-04-29 00:57:13 -07002610
solenberg2100c0b2017-03-01 11:29:29 -08002611 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002612 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002613 rtc::SetBE32(&packet[8], ssrc);
2614 DeliverPacket(packet, sizeof(packet));
2615
solenbergebb349d2017-03-13 05:46:15 -07002616 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002617 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2618 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2619 }
2620
2621 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2622 constexpr uint32_t kAnotherSsrc = 667;
2623 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002624 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002625
2626 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002627 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002628 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002629 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002630 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2631 EXPECT_EQ(2, streams[i]->received_packets());
2632 }
2633 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2634 EXPECT_EQ(1, streams[i]->received_packets());
2635 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002636 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002637}
2638
solenberg2100c0b2017-03-01 11:29:29 -08002639// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002640// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002641TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002642 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002643 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002644 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2645
2646 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002647 const uint32_t signaled_ssrc = 1;
2648 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002649 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002650 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002651 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2652 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002653 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002654
2655 // Note that the first unknown SSRC cannot be 0, because we only support
2656 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002657 const uint32_t unsignaled_ssrc = 7011;
2658 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002659 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002660 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2661 packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002662 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002663
2664 DeliverPacket(packet, sizeof(packet));
2665 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2666
2667 rtc::SetBE32(&packet[8], signaled_ssrc);
2668 DeliverPacket(packet, sizeof(packet));
2669 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002670 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002671}
2672
solenberg4904fb62017-02-17 12:01:14 -08002673// Two tests to verify that adding a receive stream with the same SSRC as a
2674// previously added unsignaled stream will only recreate underlying stream
2675// objects if the stream parameters have changed.
2676TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2677 EXPECT_TRUE(SetupChannel());
2678
2679 // Spawn unsignaled stream with SSRC=1.
2680 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002681 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002682 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2683 sizeof(kPcmuFrame)));
2684
2685 // Verify that the underlying stream object in Call is not recreated when a
2686 // stream with SSRC=1 is added.
2687 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002688 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002689 int audio_receive_stream_id = streams.front()->id();
2690 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002691 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002692 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2693}
2694
2695TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2696 EXPECT_TRUE(SetupChannel());
2697
2698 // Spawn unsignaled stream with SSRC=1.
2699 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002700 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg4904fb62017-02-17 12:01:14 -08002701 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2702 sizeof(kPcmuFrame)));
2703
2704 // Verify that the underlying stream object in Call *is* recreated when a
2705 // stream with SSRC=1 is added, and which has changed stream parameters.
2706 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002707 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002708 int audio_receive_stream_id = streams.front()->id();
2709 cricket::StreamParams stream_params;
2710 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002711 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002712 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002713 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002714 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2715}
2716
solenberg1ac56142015-10-13 03:58:19 -07002717// Test that AddRecvStream creates new stream.
2718TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002719 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002720 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721}
2722
2723// Test that after adding a recv stream, we do not decode more codecs than
2724// those previously passed into SetRecvCodecs.
2725TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002726 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002727 cricket::AudioRecvParameters parameters;
2728 parameters.codecs.push_back(kIsacCodec);
2729 parameters.codecs.push_back(kPcmuCodec);
2730 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002731 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002732 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2733 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2734 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735}
2736
2737// Test that we properly clean up any streams that were added, even if
2738// not explicitly removed.
2739TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002740 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002741 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002742 EXPECT_TRUE(AddRecvStream(1));
2743 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002744
Mirko Bonadeif859e552018-05-30 15:31:29 +02002745 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2746 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747 delete channel_;
2748 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002749 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2750 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751}
2752
wu@webrtc.org78187522013-10-07 23:32:02 +00002753TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002754 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002755 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002756}
2757
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002758TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002759 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002761 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002762}
2763
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002764// Test the InsertDtmf on default send stream as caller.
2765TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002766 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767}
2768
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002769// Test the InsertDtmf on default send stream as callee
2770TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002771 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002772}
2773
2774// Test the InsertDtmf on specified send stream as caller.
2775TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002776 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002777}
2778
2779// Test the InsertDtmf on specified send stream as callee.
2780TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002781 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002782}
2783
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002784TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002785 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002786 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002787 EXPECT_CALL(adm_,
2788 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2789 EXPECT_CALL(adm_,
2790 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2791 EXPECT_CALL(adm_,
2792 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002793
Mirko Bonadeif859e552018-05-30 15:31:29 +02002794 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002795 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796
solenberg246b8172015-12-08 09:50:23 -08002797 // Nothing set in AudioOptions, so everything should be as default.
2798 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002799 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002800 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002801 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002802 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002803
2804 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002805 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2806 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002807 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002808 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002809
2810 // Turn echo cancellation back on, with settings, and make sure
2811 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002812 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002814 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002815 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002817 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2818 // control.
solenberg76377c52017-02-21 00:54:31 -08002819 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2820 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002821 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002822 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002823
2824 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002825 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002827 send_parameters_.options.delay_agnostic_aec = false;
2828 send_parameters_.options.extended_filter_aec = false;
2829 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002830 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002831
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002832 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002833 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002835 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002836 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002837
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002838 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002839 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2840 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002841 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002842 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002843 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002844 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002845
2846 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002847 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2848 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002849 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002850 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002851 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002852 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002854 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002855 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2856 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002857 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002859 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002860 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002862 send_parameters_.options.noise_suppression = false;
2863 send_parameters_.options.highpass_filter = false;
2864 send_parameters_.options.typing_detection = false;
2865 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002866 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002867 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
solenberg1ac56142015-10-13 03:58:19 -07002869 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002870 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002872 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002874 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002875 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002877 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878}
2879
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002880TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002881 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002882 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002883 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002884 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002885 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002886 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002887 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002888 EXPECT_CALL(adm_,
2889 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2890 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2891 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002892 webrtc::AudioProcessing::Config apm_config;
2893 EXPECT_CALL(*apm_, GetConfig())
2894 .Times(10)
2895 .WillRepeatedly(ReturnPointee(&apm_config));
2896 EXPECT_CALL(*apm_, ApplyConfig(_))
2897 .Times(10)
2898 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002899 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002900
kwiberg686a8ef2016-02-26 03:00:35 -08002901 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002902 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002903 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002904 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002905 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002906 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907
2908 // Have to add a stream to make SetSend work.
2909 cricket::StreamParams stream1;
2910 stream1.ssrcs.push_back(1);
2911 channel1->AddSendStream(stream1);
2912 cricket::StreamParams stream2;
2913 stream2.ssrcs.push_back(2);
2914 channel2->AddSendStream(stream2);
2915
2916 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002917 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002918 parameters_options_all.options.echo_cancellation = true;
2919 parameters_options_all.options.auto_gain_control = true;
2920 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002921 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2922 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002923 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002924 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002925 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002926 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002927 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002928 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002929 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002930 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002931
2932 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002933 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002934 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2936 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002937 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002938 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002941 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002942 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002943 expected_options.echo_cancellation = true;
2944 expected_options.auto_gain_control = true;
2945 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002946 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947
2948 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002949 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002950 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2952 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002953 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002954 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002955 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002956 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002957 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002958 expected_options.echo_cancellation = true;
2959 expected_options.auto_gain_control = false;
2960 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002961 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962
solenberg76377c52017-02-21 00:54:31 -08002963 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2964 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002965 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002966 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002967 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002968 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002969 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002970
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2972 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002973 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002974 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002975 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002976 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002977 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2980 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002981 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002982 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002983 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002984 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002985 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002988 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2989 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002990 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2991 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002992 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2993 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002994 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002995 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002996 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002997 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002998 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002999 expected_options.echo_cancellation = true;
3000 expected_options.auto_gain_control = false;
3001 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003002 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003}
3004
wu@webrtc.orgde305012013-10-31 15:40:38 +00003005// This test verifies DSCP settings are properly applied on voice media channel.
3006TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003007 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003008 cricket::FakeNetworkInterface network_interface;
3009 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003010 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003011
peahb1c9d1d2017-07-25 15:45:24 -07003012 webrtc::AudioProcessing::Config apm_config;
3013 EXPECT_CALL(*apm_, GetConfig())
3014 .Times(3)
3015 .WillRepeatedly(ReturnPointee(&apm_config));
3016 EXPECT_CALL(*apm_, ApplyConfig(_))
3017 .Times(3)
3018 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003019 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003020
solenbergbc37fc82016-04-04 09:54:44 -07003021 channel.reset(
3022 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003023 channel->SetInterface(&network_interface);
3024 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3025 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3026
3027 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003028 channel.reset(
3029 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003030 channel->SetInterface(&network_interface);
3031 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3032
3033 // Verify that setting the option to false resets the
3034 // DiffServCodePoint.
3035 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003036 channel.reset(
3037 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003038 channel->SetInterface(&network_interface);
3039 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3040 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3041
3042 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003043}
3044
solenberg4bac9c52015-10-09 02:32:53 -07003045TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003046 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003047 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003049 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003051 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3052 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3053 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003054}
3055
solenberg2100c0b2017-03-01 11:29:29 -08003056TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003057 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003058
3059 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003060 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003061 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3062
3063 // Should remember the volume "2" which will be set on new unsignaled streams,
3064 // and also set the gain to 2 on existing unsignaled streams.
3065 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3066 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3067
3068 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3069 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3070 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3071 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3072 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3073 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3074
3075 // Setting gain with SSRC=0 should affect all unsignaled streams.
3076 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003077 if (kMaxUnsignaledRecvStreams > 1) {
3078 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3079 }
solenberg2100c0b2017-03-01 11:29:29 -08003080 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3081
3082 // Setting gain on an individual stream affects only that.
3083 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003084 if (kMaxUnsignaledRecvStreams > 1) {
3085 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3086 }
solenberg2100c0b2017-03-01 11:29:29 -08003087 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003088}
3089
Seth Hampson845e8782018-03-02 11:34:10 -08003090TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003091 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003092 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003093
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003095 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003096 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003097 // Creating two channels to make sure that sync label is set properly for both
3098 // the default voice channel and following ones.
3099 EXPECT_TRUE(channel_->AddRecvStream(sp));
3100 sp.ssrcs[0] += 1;
3101 EXPECT_TRUE(channel_->AddRecvStream(sp));
3102
Mirko Bonadeif859e552018-05-30 15:31:29 +02003103 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003104 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003105 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003106 << "SyncGroup should be set based on stream id";
3107 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003108 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003109 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003110}
3111
solenberg3a941542015-11-16 07:34:50 -08003112// TODO(solenberg): Remove, once recv streams are configured through Call.
3113// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003114TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003115 // Test that setting the header extensions results in the expected state
3116 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003117 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003118 ssrcs.push_back(223);
3119 ssrcs.push_back(224);
3120
solenbergff976312016-03-30 23:28:51 -07003121 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003122 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003123 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003124 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 cricket::StreamParams::CreateLegacy(ssrc)));
3126 }
3127
Mirko Bonadeif859e552018-05-30 15:31:29 +02003128 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003129 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003130 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003131 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003132 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003133 }
3134
3135 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003136 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003137 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003138 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003140 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003141 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003142 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 EXPECT_NE(nullptr, s);
3144 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003145 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3146 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003147 for (const auto& s_ext : s_exts) {
3148 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003149 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003150 }
3151 }
3152 }
3153 }
3154
3155 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003156 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003157 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003158 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003159 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003160 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003161 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003162}
3163
3164TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3165 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003166 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003167 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003168 static const unsigned char kRtcp[] = {
3169 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3170 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3173 };
jbaucheec21bd2016-03-20 06:15:43 -07003174 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003175
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003177 cricket::WebRtcVoiceMediaChannel* media_channel =
3178 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003179 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003180 EXPECT_TRUE(media_channel->AddRecvStream(
3181 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3182
Mirko Bonadeif859e552018-05-30 15:31:29 +02003183 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003184 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003185 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003186 EXPECT_EQ(0, s->received_packets());
3187 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3188 EXPECT_EQ(1, s->received_packets());
3189 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3190 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003191}
Minyue2013aec2015-05-13 14:14:42 +02003192
solenberg0a617e22015-10-20 15:49:38 -07003193// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003194// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003195TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003196 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003197 EXPECT_TRUE(AddRecvStream(kSsrcY));
3198 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003199 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003200 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3201 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3202 EXPECT_TRUE(AddRecvStream(kSsrcW));
3203 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003204}
3205
solenberg7602aab2016-11-14 11:30:07 -08003206TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3207 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003208 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003209 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003210 cricket::StreamParams::CreateLegacy(kSsrcY)));
3211 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3212 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3213 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003214 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003215 cricket::StreamParams::CreateLegacy(kSsrcW)));
3216 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3217 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003218}
stefan658910c2015-09-03 05:48:32 -07003219
deadbeef884f5852016-01-15 09:20:04 -08003220TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003221 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003222 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3223 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003224
3225 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003226 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3227 EXPECT_TRUE(AddRecvStream(kSsrcX));
3228 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003229
3230 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003231 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3232 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003233
3234 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003235 channel_->SetRawAudioSink(kSsrcX, nullptr);
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003237}
3238
solenberg2100c0b2017-03-01 11:29:29 -08003239TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003240 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003241 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3242 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003243 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3244 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003245
3246 // Should be able to set a default sink even when no stream exists.
3247 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3248
solenberg2100c0b2017-03-01 11:29:29 -08003249 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3250 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003251 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003253
3254 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003255 channel_->SetRawAudioSink(kSsrc0, nullptr);
3256 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003257
3258 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003259 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3260 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003261
3262 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003263 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003264 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003265 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3266
3267 // Spawn another unsignaled stream - it should be assigned the default sink
3268 // and the previous unsignaled stream should lose it.
3269 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3270 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3271 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3272 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003273 if (kMaxUnsignaledRecvStreams > 1) {
3274 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3275 }
solenberg2100c0b2017-03-01 11:29:29 -08003276 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3277
3278 // Reset the default sink - the second unsignaled stream should lose it.
3279 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003280 if (kMaxUnsignaledRecvStreams > 1) {
3281 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3282 }
solenberg2100c0b2017-03-01 11:29:29 -08003283 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3284
3285 // Try setting the default sink while two streams exists.
3286 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003287 if (kMaxUnsignaledRecvStreams > 1) {
3288 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3289 }
solenberg2100c0b2017-03-01 11:29:29 -08003290 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3291
3292 // Try setting the sink for the first unsignaled stream using its known SSRC.
3293 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003294 if (kMaxUnsignaledRecvStreams > 1) {
3295 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3296 }
solenberg2100c0b2017-03-01 11:29:29 -08003297 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003298 if (kMaxUnsignaledRecvStreams > 1) {
3299 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3300 }
deadbeef884f5852016-01-15 09:20:04 -08003301}
3302
skvlad7a43d252016-03-22 15:32:27 -07003303// Test that, just like the video channel, the voice channel communicates the
3304// network state to the call.
3305TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003306 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003307
3308 EXPECT_EQ(webrtc::kNetworkUp,
3309 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3310 EXPECT_EQ(webrtc::kNetworkUp,
3311 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3312
3313 channel_->OnReadyToSend(false);
3314 EXPECT_EQ(webrtc::kNetworkDown,
3315 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3316 EXPECT_EQ(webrtc::kNetworkUp,
3317 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3318
3319 channel_->OnReadyToSend(true);
3320 EXPECT_EQ(webrtc::kNetworkUp,
3321 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3322 EXPECT_EQ(webrtc::kNetworkUp,
3323 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3324}
3325
aleloi18e0b672016-10-04 02:45:47 -07003326// Test that playout is still started after changing parameters
3327TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3328 SetupRecvStream();
3329 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003330 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003331
3332 // Changing RTP header extensions will recreate the AudioReceiveStream.
3333 cricket::AudioRecvParameters parameters;
3334 parameters.extensions.push_back(
3335 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3336 channel_->SetRecvParameters(parameters);
3337
solenberg2100c0b2017-03-01 11:29:29 -08003338 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003339}
3340
Zhi Huangfa266ef2017-12-13 10:27:46 -08003341// Tests when GetSources is called with non-existing ssrc, it will return an
3342// empty list of RtpSource without crashing.
3343TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3344 // Setup an recv stream with |kSsrcX|.
3345 SetupRecvStream();
3346 cricket::WebRtcVoiceMediaChannel* media_channel =
3347 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3348 // Call GetSources with |kSsrcY| which doesn't exist.
3349 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3350 EXPECT_EQ(0u, sources.size());
3351}
3352
stefan658910c2015-09-03 05:48:32 -07003353// Tests that the library initializes and shuts down properly.
3354TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003355 // If the VoiceEngine wants to gather available codecs early, that's fine but
3356 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003357 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003358 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003359 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003360 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003361 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003362 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003363 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003364 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003365 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003366 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003367 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3368 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003369 EXPECT_TRUE(channel != nullptr);
3370 delete channel;
solenbergff976312016-03-30 23:28:51 -07003371}
stefan658910c2015-09-03 05:48:32 -07003372
solenbergff976312016-03-30 23:28:51 -07003373// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003374TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3375 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003376 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003377 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003378 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003379 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003380 {
peaha9cc40b2017-06-29 08:32:09 -07003381 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003382 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003383 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003384 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003385 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003386 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003387 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003388 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003389 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003390 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3391 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3392 EXPECT_TRUE(channel != nullptr);
3393 delete channel;
3394 }
stefan658910c2015-09-03 05:48:32 -07003395}
3396
ossu20a4b3f2017-04-27 02:08:52 -07003397// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3398TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003399 // TODO(ossu): Why are the payload types of codecs with non-static payload
3400 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003401 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003402 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003403 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003404 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003405 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003406 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003407 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003408 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003409 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3410 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3411 (clockrate == 0 || codec.clockrate == clockrate);
3412 };
3413 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003414 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003415 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003416 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003417 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003418 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003419 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003420 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003421 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003422 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003423 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003424 EXPECT_EQ(126, codec.id);
3425 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3426 // Remove these checks once both send and receive side assigns payload types
3427 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003428 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003429 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003430 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003431 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003432 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003433 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003434 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003435 EXPECT_EQ(111, codec.id);
3436 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3437 EXPECT_EQ("10", codec.params.find("minptime")->second);
3438 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3439 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003440 }
3441 }
stefan658910c2015-09-03 05:48:32 -07003442}
3443
3444// Tests that VoE supports at least 32 channels
3445TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003446 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003447 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003448 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003449 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003450 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003451 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003452 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003453 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003454 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003455 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003456
3457 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003458 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003459 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003460 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3461 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003462 if (!channel)
3463 break;
stefan658910c2015-09-03 05:48:32 -07003464 channels[num_channels++] = channel;
3465 }
3466
Mirko Bonadeif859e552018-05-30 15:31:29 +02003467 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003468 EXPECT_EQ(expected, num_channels);
3469
3470 while (num_channels > 0) {
3471 delete channels[--num_channels];
3472 }
stefan658910c2015-09-03 05:48:32 -07003473}
3474
3475// Test that we set our preferred codecs properly.
3476TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003477 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3478 // - Check that our builtin codecs are usable by Channel.
3479 // - The codecs provided by the engine is usable by Channel.
3480 // It does not check that the codecs in the RecvParameters are actually
3481 // what we sent in - though it's probably reasonable to expect so, if
3482 // SetRecvParameters returns true.
3483 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003484 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003485 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003486 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003487 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003488 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003489 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003490 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003491 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003492 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003493 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003494 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3495 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003496 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003497 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003498 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003499}
ossu9def8002017-02-09 05:14:32 -08003500
3501TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3502 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003503 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3504 {48000, 2, 16000, 10000, 20000}};
3505 spec1.info.allow_comfort_noise = false;
3506 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003507 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003508 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3509 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003510 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003511 specs.push_back(webrtc::AudioCodecSpec{
3512 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3513 {16000, 1, 13300}});
3514 specs.push_back(
3515 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3516 specs.push_back(
3517 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003518
ossueb1fde42017-05-02 06:46:30 -07003519 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3520 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3521 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003522 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003523 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003524 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003525 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003526
peaha9cc40b2017-06-29 08:32:09 -07003527 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003528 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003529 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003530 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003531 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003532 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003533 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003534
3535 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3536 // check the actual values safely, to provide better test results.
3537 auto get_codec =
3538 [&codecs](size_t index) -> const cricket::AudioCodec& {
3539 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3540 if (codecs.size() > index)
3541 return codecs[index];
3542 return missing_codec;
3543 };
3544
3545 // Ensure the general codecs are generated first and in order.
3546 for (size_t i = 0; i != specs.size(); ++i) {
3547 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3548 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3549 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3550 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3551 }
3552
3553 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003554 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003555 auto find_codec =
3556 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3557 for (size_t i = 0; i != codecs.size(); ++i) {
3558 const cricket::AudioCodec& codec = codecs[i];
3559 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3560 codec.clockrate == format.clockrate_hz &&
3561 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003562 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003563 }
3564 }
3565 return -1;
3566 };
3567
3568 // Ensure all supplementary codecs are generated last. Their internal ordering
3569 // is not important.
3570 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3571 const int num_specs = static_cast<int>(specs.size());
3572 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3573 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3574 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3575 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3576 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3577 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3578 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3579}