blob: 966ca6bbd6a0c358d3d2000621cfd3e3bb632482 [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);
650 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
651 EXPECT_EQ(info.packets_lost, stats.packets_lost);
652 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
653 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800654 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700655 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
656 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
657 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200658 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700659 stats.jitter_buffer_preferred_ms);
660 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
661 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700662 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
663 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200664 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200665 EXPECT_EQ(info.jitter_buffer_delay_seconds,
666 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700667 EXPECT_EQ(info.expand_rate, stats.expand_rate);
668 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
669 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200670 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700671 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
672 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200673 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700674 stats.decoding_calls_to_silence_generator);
675 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
676 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
677 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
678 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
679 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700680 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700681 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200682 }
hbos1acfbd22016-11-17 23:43:29 -0800683 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
684 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
685 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
686 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
687 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
688 codec.ToCodecParameters());
689 }
690 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
691 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
692 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
693 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
694 codec.ToCodecParameters());
695 }
696 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200697
peah8271d042016-11-22 07:24:52 -0800698 bool IsHighPassFilterEnabled() {
699 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
700 }
701
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700703 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700704 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800705 webrtc::test::MockGainControl& apm_gc_;
706 webrtc::test::MockEchoCancellation& apm_ec_;
707 webrtc::test::MockNoiseSuppression& apm_ns_;
708 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200709 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700710 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700711 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200712 cricket::AudioSendParameters send_parameters_;
713 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800714 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700715 webrtc::AudioProcessing::Config apm_config_;
716
stefanba4c0e42016-02-04 04:12:24 -0800717 private:
718 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719};
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721// Tests that we can create and destroy a channel.
722TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700723 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724}
725
solenberg31fec402016-05-06 02:13:12 -0700726// Test that we can add a send stream and that it has the correct defaults.
727TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
728 EXPECT_TRUE(SetupChannel());
729 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800730 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
731 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
732 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700733 EXPECT_EQ("", config.rtp.c_name);
734 EXPECT_EQ(0u, config.rtp.extensions.size());
735 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
736 config.send_transport);
737}
738
739// Test that we can add a receive stream and that it has the correct defaults.
740TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
741 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800742 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700743 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800744 GetRecvStreamConfig(kSsrcX);
745 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700746 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
747 EXPECT_FALSE(config.rtp.transport_cc);
748 EXPECT_EQ(0u, config.rtp.extensions.size());
749 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
750 config.rtcp_send_transport);
751 EXPECT_EQ("", config.sync_group);
752}
753
stefanba4c0e42016-02-04 04:12:24 -0800754TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700755 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800756 bool opus_found = false;
757 for (cricket::AudioCodec codec : codecs) {
758 if (codec.name == "opus") {
759 EXPECT_TRUE(HasTransportCc(codec));
760 opus_found = true;
761 }
762 }
763 EXPECT_TRUE(opus_found);
764}
765
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766// Test that we set our inbound codecs properly, including changing PT.
767TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700768 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200769 cricket::AudioRecvParameters parameters;
770 parameters.codecs.push_back(kIsacCodec);
771 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800772 parameters.codecs.push_back(kTelephoneEventCodec1);
773 parameters.codecs.push_back(kTelephoneEventCodec2);
774 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200775 parameters.codecs[2].id = 126;
776 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800777 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700778 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
779 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
780 {{0, {"PCMU", 8000, 1}},
781 {106, {"ISAC", 16000, 1}},
782 {126, {"telephone-event", 8000, 1}},
783 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784}
785
786// Test that we fail to set an unknown inbound codec.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700791 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200792 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793}
794
795// Test that we fail if we have duplicate types in the inbound list.
796TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700797 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 cricket::AudioRecvParameters parameters;
799 parameters.codecs.push_back(kIsacCodec);
800 parameters.codecs.push_back(kCn16000Codec);
801 parameters.codecs[1].id = kIsacCodec.id;
802 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803}
804
805// Test that we can decode OPUS without stereo parameters.
806TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700807 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200808 cricket::AudioRecvParameters parameters;
809 parameters.codecs.push_back(kIsacCodec);
810 parameters.codecs.push_back(kPcmuCodec);
811 parameters.codecs.push_back(kOpusCodec);
812 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800813 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700814 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
815 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
816 {{0, {"PCMU", 8000, 1}},
817 {103, {"ISAC", 16000, 1}},
818 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that we can decode OPUS with stereo = 0.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700823 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 cricket::AudioRecvParameters parameters;
825 parameters.codecs.push_back(kIsacCodec);
826 parameters.codecs.push_back(kPcmuCodec);
827 parameters.codecs.push_back(kOpusCodec);
828 parameters.codecs[2].params["stereo"] = "0";
829 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800830 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700831 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
832 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
833 {{0, {"PCMU", 8000, 1}},
834 {103, {"ISAC", 16000, 1}},
835 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836}
837
838// Test that we can decode OPUS with stereo = 1.
839TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700840 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 cricket::AudioRecvParameters parameters;
842 parameters.codecs.push_back(kIsacCodec);
843 parameters.codecs.push_back(kPcmuCodec);
844 parameters.codecs.push_back(kOpusCodec);
845 parameters.codecs[2].params["stereo"] = "1";
846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800847 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700848 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
849 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
850 {{0, {"PCMU", 8000, 1}},
851 {103, {"ISAC", 16000, 1}},
852 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that changes to recv codecs are applied to all streams.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800861 parameters.codecs.push_back(kTelephoneEventCodec1);
862 parameters.codecs.push_back(kTelephoneEventCodec2);
863 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 parameters.codecs[2].id = 126;
865 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700866 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
867 EXPECT_TRUE(AddRecvStream(ssrc));
868 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {106, {"ISAC", 16000, 1}},
872 {126, {"telephone-event", 8000, 1}},
873 {107, {"telephone-event", 32000, 1}}})));
874 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875}
876
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883
solenberg2100c0b2017-03-01 11:29:29 -0800884 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800885 ASSERT_EQ(1, dm.count(106));
886 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887}
888
889// Test that we can apply the same set of codecs again while playing.
890TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700891 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200892 cricket::AudioRecvParameters parameters;
893 parameters.codecs.push_back(kIsacCodec);
894 parameters.codecs.push_back(kCn16000Codec);
895 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700896 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898
deadbeefcb383672017-04-26 16:28:42 -0700899 // Remapping a payload type to a different codec should fail.
900 parameters.codecs[0] = kOpusCodec;
901 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800903 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904}
905
906// Test that we can add a codec while playing.
907TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700908 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200909 cricket::AudioRecvParameters parameters;
910 parameters.codecs.push_back(kIsacCodec);
911 parameters.codecs.push_back(kCn16000Codec);
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700913 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200915 parameters.codecs.push_back(kOpusCodec);
916 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800917 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
deadbeefcb383672017-04-26 16:28:42 -0700920// Test that we accept adding the same codec with a different payload type.
921// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
922TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
923 EXPECT_TRUE(SetupRecvStream());
924 cricket::AudioRecvParameters parameters;
925 parameters.codecs.push_back(kIsacCodec);
926 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
927
928 ++parameters.codecs[0].id;
929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
930}
931
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700933 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000935 // Test that when autobw is enabled, bitrate is kept as the default
936 // value. autobw is enabled for the following tests because the target
937 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938
939 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700940 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941
942 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700943 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
ossu20a4b3f2017-04-27 02:08:52 -0700945 // opus, default bitrate == 32000 in mono.
946 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947}
948
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000949TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700950 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700953 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
954 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700955 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
959 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
960 // Rates above the max (510000) should be capped.
961 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962}
963
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000964TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700965 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966
967 // Test that we can only set a maximum bitrate for a fixed-rate codec
968 // if it's bigger than the fixed rate.
969
970 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700971 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
972 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
973 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000978}
979
980TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200982 const int kDesiredBitrate = 128000;
983 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700984 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200985 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700986 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000987
988 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800989 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000990
solenberg2100c0b2017-03-01 11:29:29 -0800991 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992}
993
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994// Test that bitrate cannot be set for CBR codecs.
995// Bitrate is ignored if it is higher than the fixed bitrate.
996// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000997TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700998 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999
1000 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001001 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001002 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001003
1004 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001005 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001006 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001007
1008 send_parameters_.max_bandwidth_bps = 128;
1009 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001010 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011}
1012
skvlade0d46372016-04-07 22:59:22 -07001013// Test that the per-stream bitrate limit and the global
1014// bitrate limit both apply.
1015TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1016 EXPECT_TRUE(SetupSendStream());
1017
ossu20a4b3f2017-04-27 02:08:52 -07001018 // opus, default bitrate == 32000.
1019 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001020 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1021 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1022 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1023
1024 // CBR codecs allow both maximums to exceed the bitrate.
1025 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1026 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1029
1030 // CBR codecs don't allow per stream maximums to be too low.
1031 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1033}
1034
1035// Test that an attempt to set RtpParameters for a stream that does not exist
1036// fails.
1037TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1038 EXPECT_TRUE(SetupChannel());
1039 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001040 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001041 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1042
1043 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001044 EXPECT_FALSE(
1045 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001046}
1047
1048TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001049 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001050 // This test verifies that setting RtpParameters succeeds only if
1051 // the structure contains exactly one encoding.
1052 // TODO(skvlad): Update this test when we start supporting setting parameters
1053 // for each encoding individually.
1054
1055 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001056 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001057 // Two or more encodings should result in failure.
1058 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001059 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001060 // Zero encodings should also fail.
1061 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001062 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001063}
1064
1065// Changing the SSRC through RtpParameters is not allowed.
1066TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1067 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001068 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001069 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001070 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001071}
1072
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001073// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001074// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001075TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1076 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001077 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001081 ASSERT_EQ(1u, parameters.encodings.size());
1082 ASSERT_TRUE(parameters.encodings[0].active);
1083 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001084 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086
1087 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001088 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001089 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001090 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001091 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001092 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001093}
1094
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001095// Test that SetRtpSendParameters configures the correct encoding channel for
1096// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001097TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1098 SetupForMultiSendStream();
1099 // Create send streams.
1100 for (uint32_t ssrc : kSsrcs4) {
1101 EXPECT_TRUE(
1102 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1103 }
1104 // Configure one stream to be limited by the stream config, another to be
1105 // limited by the global max, and the third one with no per-stream limit
1106 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001107 SetGlobalMaxBitrate(kOpusCodec, 32000);
1108 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1109 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001110 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1111
ossu20a4b3f2017-04-27 02:08:52 -07001112 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1113 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1114 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001115
1116 // Remove the global cap; the streams should switch to their respective
1117 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001118 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001119 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1120 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1121 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001122}
1123
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001124// Test that GetRtpSendParameters returns the currently configured codecs.
1125TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001126 EXPECT_TRUE(SetupSendStream());
1127 cricket::AudioSendParameters parameters;
1128 parameters.codecs.push_back(kIsacCodec);
1129 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001130 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131
solenberg2100c0b2017-03-01 11:29:29 -08001132 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001133 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001134 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1135 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001136}
1137
Florent Castellidacec712018-05-24 16:24:21 +02001138// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1139TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1140 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1141 params.cname = "rtcpcname";
1142 EXPECT_TRUE(SetupSendStream(params));
1143
1144 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1145 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1146}
1147
deadbeefcb443432016-12-12 11:12:36 -08001148// Test that GetRtpSendParameters returns an SSRC.
1149TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1150 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001151 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001152 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001153 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001154}
1155
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001158 EXPECT_TRUE(SetupSendStream());
1159 cricket::AudioSendParameters parameters;
1160 parameters.codecs.push_back(kIsacCodec);
1161 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001162 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001163
solenberg2100c0b2017-03-01 11:29:29 -08001164 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165
1166 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001167 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001168
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001169 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001170 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1171 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001172}
1173
minyuececec102017-03-27 13:04:25 -07001174// Test that max_bitrate_bps in send stream config gets updated correctly when
1175// SetRtpSendParameters is called.
1176TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1177 webrtc::test::ScopedFieldTrials override_field_trials(
1178 "WebRTC-Audio-SendSideBwe/Enabled/");
1179 EXPECT_TRUE(SetupSendStream());
1180 cricket::AudioSendParameters send_parameters;
1181 send_parameters.codecs.push_back(kOpusCodec);
1182 SetSendParameters(send_parameters);
1183
1184 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1185 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1186 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1187
1188 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001189 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001190 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001191
1192 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1193 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1194}
1195
Seth Hampson24722b32017-12-22 09:36:42 -08001196// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1197// a value <= 0, setting the parameters returns false.
1198TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1199 EXPECT_TRUE(SetupSendStream());
1200 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1201 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1202 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1203 rtp_parameters.encodings[0].bitrate_priority);
1204
1205 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001206 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001207 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001208 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001209}
1210
1211// Test that the bitrate_priority in the send stream config gets updated when
1212// SetRtpSendParameters is set for the VoiceMediaChannel.
1213TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1214 EXPECT_TRUE(SetupSendStream());
1215 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1216
1217 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1218 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1219 rtp_parameters.encodings[0].bitrate_priority);
1220 double new_bitrate_priority = 2.0;
1221 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001222 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001223
1224 // The priority should get set for both the audio channel's rtp parameters
1225 // and the audio send stream's audio config.
1226 EXPECT_EQ(
1227 new_bitrate_priority,
1228 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1229 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1230}
1231
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001232// Test that GetRtpReceiveParameters returns the currently configured codecs.
1233TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1234 EXPECT_TRUE(SetupRecvStream());
1235 cricket::AudioRecvParameters parameters;
1236 parameters.codecs.push_back(kIsacCodec);
1237 parameters.codecs.push_back(kPcmuCodec);
1238 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1239
1240 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001241 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001242 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1243 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1244 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1245}
1246
deadbeefcb443432016-12-12 11:12:36 -08001247// Test that GetRtpReceiveParameters returns an SSRC.
1248TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1249 EXPECT_TRUE(SetupRecvStream());
1250 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001251 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001252 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001253 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001254}
1255
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001256// Test that if we set/get parameters multiple times, we get the same results.
1257TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1258 EXPECT_TRUE(SetupRecvStream());
1259 cricket::AudioRecvParameters parameters;
1260 parameters.codecs.push_back(kIsacCodec);
1261 parameters.codecs.push_back(kPcmuCodec);
1262 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1263
1264 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001265 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001266
1267 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001268 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001269
1270 // ... And this shouldn't change the params returned by
1271 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001272 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1273 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001274}
1275
deadbeef3bc15102017-04-20 19:25:07 -07001276// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1277// aren't signaled. It should return an empty "RtpEncodingParameters" when
1278// configured to receive an unsignaled stream and no packets have been received
1279// yet, and start returning the SSRC once a packet has been received.
1280TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1281 ASSERT_TRUE(SetupChannel());
1282 // Call necessary methods to configure receiving a default stream as
1283 // soon as it arrives.
1284 cricket::AudioRecvParameters parameters;
1285 parameters.codecs.push_back(kIsacCodec);
1286 parameters.codecs.push_back(kPcmuCodec);
1287 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1288
1289 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1290 // stream. Should return nothing.
1291 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1292
1293 // Set a sink for an unsignaled stream.
1294 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1295 // Value of "0" means "unsignaled stream".
1296 channel_->SetRawAudioSink(0, std::move(fake_sink));
1297
1298 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1299 // in this method means "unsignaled stream".
1300 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1301 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1302 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1303
1304 // Receive PCMU packet (SSRC=1).
1305 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1306
1307 // The |ssrc| member should still be unset.
1308 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1309 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1310 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1311}
1312
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313// Test that we apply codecs properly.
1314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kIsacCodec);
1318 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001319 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001320 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001321 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001322 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001323 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1324 EXPECT_EQ(96, send_codec_spec.payload_type);
1325 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1326 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1327 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001328 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001329 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330}
1331
ossu20a4b3f2017-04-27 02:08:52 -07001332// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1333// AudioSendStream.
1334TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001335 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001336 cricket::AudioSendParameters parameters;
1337 parameters.codecs.push_back(kIsacCodec);
1338 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001339 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 parameters.codecs[0].id = 96;
1341 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001342 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001343 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001344 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001345 // Calling SetSendCodec again with same codec which is already set.
1346 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001347 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001348 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001349}
1350
ossu20a4b3f2017-04-27 02:08:52 -07001351// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1352// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001353
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001354// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001356 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001357 cricket::AudioSendParameters parameters;
1358 parameters.codecs.push_back(kOpusCodec);
1359 parameters.codecs[0].bitrate = 0;
1360 parameters.codecs[0].clockrate = 50000;
1361 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001364// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kOpusCodec);
1369 parameters.codecs[0].bitrate = 0;
1370 parameters.codecs[0].channels = 0;
1371 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372}
1373
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001374// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001376 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 cricket::AudioSendParameters parameters;
1378 parameters.codecs.push_back(kOpusCodec);
1379 parameters.codecs[0].bitrate = 0;
1380 parameters.codecs[0].channels = 0;
1381 parameters.codecs[0].params["stereo"] = "1";
1382 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383}
1384
1385// Test that if channel is 1 for opus and there's no stereo, we fail.
1386TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001387 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 cricket::AudioSendParameters parameters;
1389 parameters.codecs.push_back(kOpusCodec);
1390 parameters.codecs[0].bitrate = 0;
1391 parameters.codecs[0].channels = 1;
1392 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393}
1394
1395// Test that if channel is 1 for opus and stereo=0, we fail.
1396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].bitrate = 0;
1401 parameters.codecs[0].channels = 1;
1402 parameters.codecs[0].params["stereo"] = "0";
1403 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404}
1405
1406// Test that if channel is 1 for opus and stereo=1, we fail.
1407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001408 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 cricket::AudioSendParameters parameters;
1410 parameters.codecs.push_back(kOpusCodec);
1411 parameters.codecs[0].bitrate = 0;
1412 parameters.codecs[0].channels = 1;
1413 parameters.codecs[0].params["stereo"] = "1";
1414 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
ossu20a4b3f2017-04-27 02:08:52 -07001417// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425}
1426
ossu20a4b3f2017-04-27 02:08:52 -07001427// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].bitrate = 0;
1433 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436}
1437
ossu20a4b3f2017-04-27 02:08:52 -07001438// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001444 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001448
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001451 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001452}
1453
ossu20a4b3f2017-04-27 02:08:52 -07001454// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 0;
1460 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001462 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
ossu20a4b3f2017-04-27 02:08:52 -07001465// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001471 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001473 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001474 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001475
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001478 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001479}
1480
ossu20a4b3f2017-04-27 02:08:52 -07001481// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001483 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 cricket::AudioSendParameters parameters;
1485 parameters.codecs.push_back(kOpusCodec);
1486 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001487 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001488 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1489 EXPECT_EQ(111, spec.payload_type);
1490 EXPECT_EQ(96000, spec.target_bitrate_bps);
1491 EXPECT_EQ("opus", spec.format.name);
1492 EXPECT_EQ(2, spec.format.num_channels);
1493 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494}
1495
ossu20a4b3f2017-04-27 02:08:52 -07001496// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001497TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001498 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001499 cricket::AudioSendParameters parameters;
1500 parameters.codecs.push_back(kOpusCodec);
1501 parameters.codecs[0].bitrate = 30000;
1502 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001504 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505}
1506
ossu20a4b3f2017-04-27 02:08:52 -07001507// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001513 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001514 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001515}
1516
ossu20a4b3f2017-04-27 02:08:52 -07001517// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001518TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001519 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001520 cricket::AudioSendParameters parameters;
1521 parameters.codecs.push_back(kOpusCodec);
1522 parameters.codecs[0].bitrate = 30000;
1523 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001525 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001526}
1527
stefan13f1a0a2016-11-30 07:22:58 -08001528TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1529 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1530 200000);
1531}
1532
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1534 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1535}
1536
1537TEST_F(WebRtcVoiceEngineTestFake,
1538 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1539 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1540}
1541
1542TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1543 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1544}
1545
1546TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001547 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001548 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1549 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001550 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001551 // Setting max bitrate should keep previous min bitrate
1552 // Setting max bitrate should not reset start bitrate.
1553 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1554 SetSdpBitrateParameters(
1555 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1556 Field(&BitrateConstraints::start_bitrate_bps, -1),
1557 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001558 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001559}
1560
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001561// Test that we can enable NACK with opus as caller.
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].AddFeedbackParam(
1567 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1568 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001569 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001570 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572}
1573
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001574// Test that we can enable NACK with opus as callee.
1575TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001576 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 cricket::AudioSendParameters parameters;
1578 parameters.codecs.push_back(kOpusCodec);
1579 parameters.codecs[0].AddFeedbackParam(
1580 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1581 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001584 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001586
1587 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001588 cricket::StreamParams::CreateLegacy(kSsrcX)));
1589 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001590}
1591
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592// Test that we can enable NACK on receive streams.
1593TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001594 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001595 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 cricket::AudioSendParameters parameters;
1597 parameters.codecs.push_back(kOpusCodec);
1598 parameters.codecs[0].AddFeedbackParam(
1599 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1600 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1602 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606}
1607
1608// Test that we can disable NACK.
1609TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001610 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001611 cricket::AudioSendParameters parameters;
1612 parameters.codecs.push_back(kOpusCodec);
1613 parameters.codecs[0].AddFeedbackParam(
1614 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1615 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001616 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001617 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 parameters.codecs.clear();
1620 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623}
1624
1625// Test that we can disable NACK on receive streams.
1626TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001627 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 cricket::AudioSendParameters parameters;
1630 parameters.codecs.push_back(kOpusCodec);
1631 parameters.codecs[0].AddFeedbackParam(
1632 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1633 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001635 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1636 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001638 parameters.codecs.clear();
1639 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001640 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001641 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1642 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643}
1644
1645// Test that NACK is enabled on a new receive stream.
1646TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001647 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001648 cricket::AudioSendParameters parameters;
1649 parameters.codecs.push_back(kIsacCodec);
1650 parameters.codecs.push_back(kCn16000Codec);
1651 parameters.codecs[0].AddFeedbackParam(
1652 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1653 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001655 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656
solenberg2100c0b2017-03-01 11:29:29 -08001657 EXPECT_TRUE(AddRecvStream(kSsrcY));
1658 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1659 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1660 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661}
1662
stefanba4c0e42016-02-04 04:12:24 -08001663TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001664 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001665 cricket::AudioSendParameters send_parameters;
1666 send_parameters.codecs.push_back(kOpusCodec);
1667 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001668 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001669
1670 cricket::AudioRecvParameters recv_parameters;
1671 recv_parameters.codecs.push_back(kIsacCodec);
1672 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001673 EXPECT_TRUE(AddRecvStream(kSsrcX));
1674 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001675 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001676 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001677
ossudedfd282016-06-14 07:12:39 -07001678 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001679 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001680 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001681 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001682 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001683}
1684
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001685// Test that we can switch back and forth between Opus and ISAC with CN.
1686TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001688
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters opus_parameters;
1690 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(111, spec.payload_type);
1695 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001696 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001698 cricket::AudioSendParameters isac_parameters;
1699 isac_parameters.codecs.push_back(kIsacCodec);
1700 isac_parameters.codecs.push_back(kCn16000Codec);
1701 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001703 {
ossu20a4b3f2017-04-27 02:08:52 -07001704 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1705 EXPECT_EQ(103, spec.payload_type);
1706 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001707 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001708
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001710 {
ossu20a4b3f2017-04-27 02:08:52 -07001711 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1712 EXPECT_EQ(111, spec.payload_type);
1713 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001714 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715}
1716
1717// Test that we handle various ways of specifying bitrate.
1718TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001719 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 cricket::AudioSendParameters parameters;
1721 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001723 {
ossu20a4b3f2017-04-27 02:08:52 -07001724 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1725 EXPECT_EQ(103, spec.payload_type);
1726 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1727 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001728 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001730 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001731 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001732 {
ossu20a4b3f2017-04-27 02:08:52 -07001733 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1734 EXPECT_EQ(103, spec.payload_type);
1735 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1736 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001737 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001738 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001740 {
ossu20a4b3f2017-04-27 02:08:52 -07001741 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1742 EXPECT_EQ(103, spec.payload_type);
1743 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1744 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001745 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001746
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001749 {
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(0, spec.payload_type);
1752 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1753 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001758 {
ossu20a4b3f2017-04-27 02:08:52 -07001759 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1760 EXPECT_EQ(0, spec.payload_type);
1761 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1762 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001763 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 parameters.codecs[0] = kOpusCodec;
1766 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001768 {
ossu20a4b3f2017-04-27 02:08:52 -07001769 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1770 EXPECT_EQ(111, spec.payload_type);
1771 EXPECT_STREQ("opus", spec.format.name.c_str());
1772 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001773 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774}
1775
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001776// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001777TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001778 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 cricket::AudioSendParameters parameters;
1780 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001781}
1782
1783// Test that we can set send codecs even with telephone-event codec as the first
1784// one on the list.
1785TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001786 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001788 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001789 parameters.codecs.push_back(kIsacCodec);
1790 parameters.codecs.push_back(kPcmuCodec);
1791 parameters.codecs[0].id = 98; // DTMF
1792 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001794 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1795 EXPECT_EQ(96, spec.payload_type);
1796 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001797 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001798 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001799}
1800
Harald Alvestranda1f66612018-02-21 11:24:23 +01001801// Test that CanInsertDtmf() is governed by the send flag
1802TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1803 EXPECT_TRUE(SetupSendStream());
1804 cricket::AudioSendParameters parameters;
1805 parameters.codecs.push_back(kTelephoneEventCodec1);
1806 parameters.codecs.push_back(kPcmuCodec);
1807 parameters.codecs[0].id = 98; // DTMF
1808 parameters.codecs[1].id = 96;
1809 SetSendParameters(parameters);
1810 EXPECT_FALSE(channel_->CanInsertDtmf());
1811 SetSend(true);
1812 EXPECT_TRUE(channel_->CanInsertDtmf());
1813 SetSend(false);
1814 EXPECT_FALSE(channel_->CanInsertDtmf());
1815}
1816
solenberg31642aa2016-03-14 08:00:37 -07001817// Test that payload type range is limited for telephone-event codec.
1818TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001819 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001820 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001821 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001822 parameters.codecs.push_back(kIsacCodec);
1823 parameters.codecs[0].id = 0; // DTMF
1824 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001826 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001827 EXPECT_TRUE(channel_->CanInsertDtmf());
1828 parameters.codecs[0].id = 128; // DTMF
1829 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1830 EXPECT_FALSE(channel_->CanInsertDtmf());
1831 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001832 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001833 EXPECT_TRUE(channel_->CanInsertDtmf());
1834 parameters.codecs[0].id = -1; // DTMF
1835 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1836 EXPECT_FALSE(channel_->CanInsertDtmf());
1837}
1838
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001839// Test that we can set send codecs even with CN codec as the first
1840// one on the list.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001842 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 cricket::AudioSendParameters parameters;
1844 parameters.codecs.push_back(kCn16000Codec);
1845 parameters.codecs.push_back(kIsacCodec);
1846 parameters.codecs.push_back(kPcmuCodec);
1847 parameters.codecs[0].id = 98; // wideband CN
1848 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001849 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001850 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1851 EXPECT_EQ(96, send_codec_spec.payload_type);
1852 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001853 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854}
1855
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001856// Test that we set VAD and DTMF types correctly as caller.
1857TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001858 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 cricket::AudioSendParameters parameters;
1860 parameters.codecs.push_back(kIsacCodec);
1861 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001862 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001863 parameters.codecs.push_back(kCn16000Codec);
1864 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001865 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001866 parameters.codecs[0].id = 96;
1867 parameters.codecs[2].id = 97; // wideband CN
1868 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001869 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001870 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1871 EXPECT_EQ(96, send_codec_spec.payload_type);
1872 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1873 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001874 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001875 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001876 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001877}
1878
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001879// Test that we set VAD and DTMF types correctly as callee.
1880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001881 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters parameters;
1883 parameters.codecs.push_back(kIsacCodec);
1884 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001885 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 parameters.codecs.push_back(kCn16000Codec);
1887 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001888 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 parameters.codecs[0].id = 96;
1890 parameters.codecs[2].id = 97; // wideband CN
1891 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001893 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001894 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001895
ossu20a4b3f2017-04-27 02:08:52 -07001896 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1897 EXPECT_EQ(96, send_codec_spec.payload_type);
1898 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1899 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001900 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001901 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001902 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001903}
1904
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001905// Test that we only apply VAD if we have a CN codec that matches the
1906// send codec clockrate.
1907TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001908 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 parameters.codecs.push_back(kIsacCodec);
1912 parameters.codecs.push_back(kCn16000Codec);
1913 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001914 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001915 {
ossu20a4b3f2017-04-27 02:08:52 -07001916 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1917 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1918 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001919 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001920 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001921 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001922 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001923 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001924 {
ossu20a4b3f2017-04-27 02:08:52 -07001925 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1926 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001927 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001928 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001931 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001932 {
ossu20a4b3f2017-04-27 02:08:52 -07001933 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1934 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1935 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001936 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001937 }
Brave Yao5225dd82015-03-26 07:39:19 +08001938 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001939 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001940 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001941 {
ossu20a4b3f2017-04-27 02:08:52 -07001942 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1943 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001944 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001945 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001946}
1947
1948// Test that we perform case-insensitive matching of codec names.
1949TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001950 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001951 cricket::AudioSendParameters parameters;
1952 parameters.codecs.push_back(kIsacCodec);
1953 parameters.codecs.push_back(kPcmuCodec);
1954 parameters.codecs.push_back(kCn16000Codec);
1955 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001956 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001957 parameters.codecs[0].name = "iSaC";
1958 parameters.codecs[0].id = 96;
1959 parameters.codecs[2].id = 97; // wideband CN
1960 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001962 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1963 EXPECT_EQ(96, send_codec_spec.payload_type);
1964 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1965 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001966 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001967 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001968 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969}
1970
stefanba4c0e42016-02-04 04:12:24 -08001971class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1972 public:
1973 WebRtcVoiceEngineWithSendSideBweTest()
1974 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1975};
1976
1977TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1978 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001979 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001980 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001981 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1982 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1983 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001984 extension.id);
1985 return;
1986 }
1987 }
1988 FAIL() << "Transport sequence number extension not in header-extension list.";
1989}
1990
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001991// Test support for audio level header extension.
1992TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001993 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001994}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001995TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001996 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001997}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001998
solenbergd4adce42016-11-17 06:26:52 -08001999// Test support for transport sequence number header extension.
2000TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2001 TestSetSendRtpHeaderExtensions(
2002 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002003}
solenbergd4adce42016-11-17 06:26:52 -08002004TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2005 TestSetRecvRtpHeaderExtensions(
2006 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002007}
2008
solenberg1ac56142015-10-13 03:58:19 -07002009// Test that we can create a channel and start sending on it.
2010TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002011 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002012 SetSendParameters(send_parameters_);
2013 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002014 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002015 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002016 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002017}
2018
2019// Test that a channel will send if and only if it has a source and is enabled
2020// for sending.
2021TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002022 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002023 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002024 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002025 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002026 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2027 SetAudioSend(kSsrcX, true, &fake_source_);
2028 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2029 SetAudioSend(kSsrcX, true, nullptr);
2030 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002031}
2032
solenberg94218532016-06-16 10:53:22 -07002033// Test that a channel is muted/unmuted.
2034TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2035 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002036 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002037 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2038 SetAudioSend(kSsrcX, true, nullptr);
2039 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2040 SetAudioSend(kSsrcX, false, nullptr);
2041 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002042}
2043
solenberg6d6e7c52016-04-13 09:07:30 -07002044// Test that SetSendParameters() does not alter a stream's send state.
2045TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2046 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002047 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002048
2049 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002050 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002051 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002052
2053 // Changing RTP header extensions will recreate the AudioSendStream.
2054 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002055 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002056 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002057 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002058
2059 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002060 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002061 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002062
2063 // Changing RTP header extensions will recreate the AudioSendStream.
2064 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002065 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002066 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002067}
2068
solenberg1ac56142015-10-13 03:58:19 -07002069// Test that we can create a channel and start playing out on it.
2070TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002071 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002072 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002073 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002074 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002075 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002076 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002077}
2078
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079// Test that we can add and remove send streams.
2080TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2081 SetupForMultiSendStream();
2082
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002084 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002085
solenbergc96df772015-10-21 13:01:53 -07002086 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002088 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002089 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002090 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002091 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002092 }
tfarina5237aaf2015-11-10 23:44:30 -08002093 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094
solenbergc96df772015-10-21 13:01:53 -07002095 // Delete the send streams.
2096 for (uint32_t ssrc : kSsrcs4) {
2097 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002098 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002099 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002100 }
solenbergc96df772015-10-21 13:01:53 -07002101 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102}
2103
2104// Test SetSendCodecs correctly configure the codecs in all send streams.
2105TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2106 SetupForMultiSendStream();
2107
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002109 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002111 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 }
2113
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002114 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002116 parameters.codecs.push_back(kIsacCodec);
2117 parameters.codecs.push_back(kCn16000Codec);
2118 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120
2121 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002122 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002123 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2124 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002125 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2126 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2127 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002128 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129 }
2130
minyue7a973442016-10-20 03:27:12 -07002131 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002132 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002133 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002134 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002135 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2136 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002137 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2138 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002139 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140 }
2141}
2142
2143// Test we can SetSend on all send streams correctly.
2144TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2145 SetupForMultiSendStream();
2146
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002147 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002148 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002149 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002150 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002151 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002152 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
2154
2155 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002156 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002157 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002159 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002160 }
2161
2162 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002163 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002164 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002166 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002167 }
2168}
2169
2170// Test we can set the correct statistics on all send streams.
2171TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2172 SetupForMultiSendStream();
2173
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002174 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002175 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002177 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002178 }
solenberg85a04962015-10-27 03:35:21 -07002179
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002180 // Create a receive stream to check that none of the send streams end up in
2181 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002183
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002184 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002185 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002186 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002187 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002188
solenberg85a04962015-10-27 03:35:21 -07002189 // Check stats for the added streams.
2190 {
2191 cricket::VoiceMediaInfo info;
2192 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002193
solenberg85a04962015-10-27 03:35:21 -07002194 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002195 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002196 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002197 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002198 }
hbos1acfbd22016-11-17 23:43:29 -08002199 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002200
2201 // We have added one receive stream. We should see empty stats.
2202 EXPECT_EQ(info.receivers.size(), 1u);
2203 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002204 }
solenberg1ac56142015-10-13 03:58:19 -07002205
solenberg2100c0b2017-03-01 11:29:29 -08002206 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002207 {
2208 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002209 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002210 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002211 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002212 EXPECT_EQ(0u, info.receivers.size());
2213 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002214
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002215 // Deliver a new packet - a default receive stream should be created and we
2216 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002217 {
2218 cricket::VoiceMediaInfo info;
2219 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2220 SetAudioReceiveStreamStats();
2221 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002222 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002223 EXPECT_EQ(1u, info.receivers.size());
2224 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002225 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002226 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227}
2228
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002229// Test that we can add and remove receive streams, and do proper send/playout.
2230// We can receive on multiple streams while sending one stream.
2231TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002232 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002233
solenberg1ac56142015-10-13 03:58:19 -07002234 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002236 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002237
solenberg1ac56142015-10-13 03:58:19 -07002238 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002239 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002240 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002241 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002242
solenberg1ac56142015-10-13 03:58:19 -07002243 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002244 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002245
2246 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002247 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2248 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2249 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250
2251 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002252 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002253 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002254
2255 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002256 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002257 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2258 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002259
aleloi84ef6152016-08-04 05:28:21 -07002260 // Restart playout and make sure recv streams are played out.
2261 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2263 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002264
aleloi84ef6152016-08-04 05:28:21 -07002265 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002266 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2267 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002268}
2269
wu@webrtc.org97077a32013-10-25 21:18:33 +00002270TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002271 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002272 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2273 .Times(1)
2274 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002275 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2276 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002277 send_parameters_.options.tx_agc_target_dbov = 3;
2278 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2279 send_parameters_.options.tx_agc_limiter = true;
2280 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002281 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2282 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2283 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002284 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002285}
2286
minyue6b825df2016-10-31 04:08:32 -07002287TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2288 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002289 send_parameters_.options.audio_network_adaptor = true;
2290 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002291 SetSendParameters(send_parameters_);
2292 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002293 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002294}
2295
2296TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2297 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002298 send_parameters_.options.audio_network_adaptor = true;
2299 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002300 SetSendParameters(send_parameters_);
2301 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002302 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002303 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002304 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002305 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002306 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002307}
2308
2309TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2310 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002311 send_parameters_.options.audio_network_adaptor = true;
2312 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002313 SetSendParameters(send_parameters_);
2314 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002315 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002316 const int initial_num = call_.GetNumCreatedSendStreams();
2317 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002318 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002319 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2320 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002321 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002322 // AudioSendStream not expected to be recreated.
2323 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2324 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002325 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002326}
2327
michaelt6672b262017-01-11 10:17:59 -08002328class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2329 : public WebRtcVoiceEngineTestFake {
2330 public:
2331 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2332 : WebRtcVoiceEngineTestFake(
2333 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2334 "Enabled/") {}
2335};
2336
2337TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2338 EXPECT_TRUE(SetupSendStream());
2339 cricket::AudioSendParameters parameters;
2340 parameters.codecs.push_back(kOpusCodec);
2341 SetSendParameters(parameters);
2342 const int initial_num = call_.GetNumCreatedSendStreams();
2343 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2344
2345 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2346 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002347 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2348 constexpr int kMinOverheadBps =
2349 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002350
2351 constexpr int kOpusMinBitrateBps = 6000;
2352 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002353 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002354 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002355 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002356 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002357
Oskar Sundbom78807582017-11-16 11:09:55 +01002358 parameters.options.audio_network_adaptor = true;
2359 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002360 SetSendParameters(parameters);
2361
ossu11bfc532017-02-16 05:37:06 -08002362 constexpr int kMinOverheadWithAnaBps =
2363 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002364
2365 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002366 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002367
minyuececec102017-03-27 13:04:25 -07002368 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002369 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002370}
2371
minyuececec102017-03-27 13:04:25 -07002372// This test is similar to
2373// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2374// additional field trial.
2375TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2376 SetRtpSendParameterUpdatesMaxBitrate) {
2377 EXPECT_TRUE(SetupSendStream());
2378 cricket::AudioSendParameters send_parameters;
2379 send_parameters.codecs.push_back(kOpusCodec);
2380 SetSendParameters(send_parameters);
2381
2382 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2383 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2384 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2385
2386 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002387 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002388 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002389
2390 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2391#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2392 constexpr int kMinOverhead = 3333;
2393#else
2394 constexpr int kMinOverhead = 6666;
2395#endif
2396 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2397}
2398
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002399// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002400// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002402 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002403 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002404}
2405
2406TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2407 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002408 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002409 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002410 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002411 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002412 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002413 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002414 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415
solenberg85a04962015-10-27 03:35:21 -07002416 // Check stats for the added streams.
2417 {
2418 cricket::VoiceMediaInfo info;
2419 EXPECT_EQ(true, channel_->GetStats(&info));
2420
2421 // We have added one send stream. We should see the stats we've set.
2422 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002423 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002424 // We have added one receive stream. We should see empty stats.
2425 EXPECT_EQ(info.receivers.size(), 1u);
2426 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2427 }
solenberg1ac56142015-10-13 03:58:19 -07002428
solenberg566ef242015-11-06 15:34:49 -08002429 // Start sending - this affects some reported stats.
2430 {
2431 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002432 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002433 EXPECT_EQ(true, channel_->GetStats(&info));
2434 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002435 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002436 }
2437
solenberg2100c0b2017-03-01 11:29:29 -08002438 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002439 {
2440 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002441 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002442 EXPECT_EQ(true, channel_->GetStats(&info));
2443 EXPECT_EQ(1u, info.senders.size());
2444 EXPECT_EQ(0u, info.receivers.size());
2445 }
solenberg1ac56142015-10-13 03:58:19 -07002446
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002447 // Deliver a new packet - a default receive stream should be created and we
2448 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002449 {
2450 cricket::VoiceMediaInfo info;
2451 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2452 SetAudioReceiveStreamStats();
2453 EXPECT_EQ(true, channel_->GetStats(&info));
2454 EXPECT_EQ(1u, info.senders.size());
2455 EXPECT_EQ(1u, info.receivers.size());
2456 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002457 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002458 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459}
2460
2461// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002462// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002464 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002465 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2466 EXPECT_TRUE(AddRecvStream(kSsrcY));
2467 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002468}
2469
2470// Test that the local SSRC is the same on sending and receiving channels if the
2471// receive channel is created before the send channel.
2472TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002473 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002474 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002476 cricket::StreamParams::CreateLegacy(kSsrcX)));
2477 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2478 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479}
2480
2481// Test that we can properly receive packets.
2482TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002483 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002484 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002486
2487 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2488 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489}
2490
2491// Test that we can properly receive packets on multiple streams.
2492TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002493 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002494 const uint32_t ssrc1 = 1;
2495 const uint32_t ssrc2 = 2;
2496 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002497 EXPECT_TRUE(AddRecvStream(ssrc1));
2498 EXPECT_TRUE(AddRecvStream(ssrc2));
2499 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002501 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002502 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002504 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505 }
mflodman3d7db262016-04-29 00:57:13 -07002506
2507 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2508 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2509 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2510
2511 EXPECT_EQ(s1.received_packets(), 0);
2512 EXPECT_EQ(s2.received_packets(), 0);
2513 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002514
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002515 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002516 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[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002521 EXPECT_EQ(s1.received_packets(), 1);
2522 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2523 EXPECT_EQ(s2.received_packets(), 0);
2524 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002525
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002527 EXPECT_EQ(s1.received_packets(), 1);
2528 EXPECT_EQ(s2.received_packets(), 1);
2529 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2530 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002531
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002532 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002533 EXPECT_EQ(s1.received_packets(), 1);
2534 EXPECT_EQ(s2.received_packets(), 1);
2535 EXPECT_EQ(s3.received_packets(), 1);
2536 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002537
mflodman3d7db262016-04-29 00:57:13 -07002538 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2539 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2540 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002541}
2542
solenberg2100c0b2017-03-01 11:29:29 -08002543// Test that receiving on an unsignaled stream works (a stream is created).
2544TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002545 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002546 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2547
solenberg7e63ef02015-11-20 00:19:43 -08002548 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002549
2550 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002551 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2552 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002553}
2554
Seth Hampson5897a6e2018-04-03 11:16:33 -07002555// Tests that when we add a stream without SSRCs, but contains a stream_id
2556// that it is stored and its stream id is later used when the first packet
2557// arrives to properly create a receive stream with a sync label.
2558TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2559 const char kSyncLabel[] = "sync_label";
2560 EXPECT_TRUE(SetupChannel());
2561 cricket::StreamParams unsignaled_stream;
2562 unsignaled_stream.set_stream_ids({kSyncLabel});
2563 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2564 // The stream shouldn't have been created at this point because it doesn't
2565 // have any SSRCs.
2566 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2567
2568 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2569
2570 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2571 EXPECT_TRUE(
2572 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2573 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2574
2575 // Removing the unsignaled stream clears the cached parameters. If a new
2576 // default unsignaled receive stream is created it will not have a sync group.
2577 channel_->RemoveRecvStream(0);
2578 channel_->RemoveRecvStream(kSsrc1);
2579
2580 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2581
2582 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2583 EXPECT_TRUE(
2584 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2585 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2586}
2587
solenberg2100c0b2017-03-01 11:29:29 -08002588// Test that receiving N unsignaled stream works (streams will be created), and
2589// that packets are forwarded to them all.
2590TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002591 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002592 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002593 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2594
solenberg2100c0b2017-03-01 11:29:29 -08002595 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002596 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002597 rtc::SetBE32(&packet[8], ssrc);
2598 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002599
solenberg2100c0b2017-03-01 11:29:29 -08002600 // Verify we have one new stream for each loop iteration.
2601 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002602 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2603 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002604 }
mflodman3d7db262016-04-29 00:57:13 -07002605
solenberg2100c0b2017-03-01 11:29:29 -08002606 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002607 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002608 rtc::SetBE32(&packet[8], ssrc);
2609 DeliverPacket(packet, sizeof(packet));
2610
solenbergebb349d2017-03-13 05:46:15 -07002611 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002612 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2613 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2614 }
2615
2616 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2617 constexpr uint32_t kAnotherSsrc = 667;
2618 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002619 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002620
2621 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002622 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002623 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002624 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002625 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2626 EXPECT_EQ(2, streams[i]->received_packets());
2627 }
2628 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2629 EXPECT_EQ(1, streams[i]->received_packets());
2630 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002631 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002632}
2633
solenberg2100c0b2017-03-01 11:29:29 -08002634// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002635// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002636TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002637 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002638 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002639 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2640
2641 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002642 const uint32_t signaled_ssrc = 1;
2643 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002644 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002645 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002646 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2647 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002648 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002649
2650 // Note that the first unknown SSRC cannot be 0, because we only support
2651 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002652 const uint32_t unsignaled_ssrc = 7011;
2653 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002654 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002655 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2656 packet, sizeof(packet)));
2657 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2658
2659 DeliverPacket(packet, sizeof(packet));
2660 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2661
2662 rtc::SetBE32(&packet[8], signaled_ssrc);
2663 DeliverPacket(packet, sizeof(packet));
2664 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2665 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002666}
2667
solenberg4904fb62017-02-17 12:01:14 -08002668// Two tests to verify that adding a receive stream with the same SSRC as a
2669// previously added unsignaled stream will only recreate underlying stream
2670// objects if the stream parameters have changed.
2671TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2672 EXPECT_TRUE(SetupChannel());
2673
2674 // Spawn unsignaled stream with SSRC=1.
2675 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2676 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2677 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2678 sizeof(kPcmuFrame)));
2679
2680 // Verify that the underlying stream object in Call is not recreated when a
2681 // stream with SSRC=1 is added.
2682 const auto& streams = call_.GetAudioReceiveStreams();
2683 EXPECT_EQ(1, streams.size());
2684 int audio_receive_stream_id = streams.front()->id();
2685 EXPECT_TRUE(AddRecvStream(1));
2686 EXPECT_EQ(1, streams.size());
2687 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2688}
2689
2690TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2691 EXPECT_TRUE(SetupChannel());
2692
2693 // Spawn unsignaled stream with SSRC=1.
2694 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2695 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2696 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2697 sizeof(kPcmuFrame)));
2698
2699 // Verify that the underlying stream object in Call *is* recreated when a
2700 // stream with SSRC=1 is added, and which has changed stream parameters.
2701 const auto& streams = call_.GetAudioReceiveStreams();
2702 EXPECT_EQ(1, streams.size());
2703 int audio_receive_stream_id = streams.front()->id();
2704 cricket::StreamParams stream_params;
2705 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002706 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002707 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2708 EXPECT_EQ(1, streams.size());
2709 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2710}
2711
solenberg1ac56142015-10-13 03:58:19 -07002712// Test that AddRecvStream creates new stream.
2713TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002714 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002715 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716}
2717
2718// Test that after adding a recv stream, we do not decode more codecs than
2719// those previously passed into SetRecvCodecs.
2720TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002721 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002722 cricket::AudioRecvParameters parameters;
2723 parameters.codecs.push_back(kIsacCodec);
2724 parameters.codecs.push_back(kPcmuCodec);
2725 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002726 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002727 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2728 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2729 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730}
2731
2732// Test that we properly clean up any streams that were added, even if
2733// not explicitly removed.
2734TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002735 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002736 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002737 EXPECT_TRUE(AddRecvStream(1));
2738 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002739
2740 EXPECT_EQ(1, call_.GetAudioSendStreams().size());
2741 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742 delete channel_;
2743 channel_ = NULL;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002744 EXPECT_EQ(0, call_.GetAudioSendStreams().size());
2745 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746}
2747
wu@webrtc.org78187522013-10-07 23:32:02 +00002748TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002749 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002750 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002751}
2752
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002753TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002754 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002755 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002756 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002757}
2758
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002759// Test the InsertDtmf on default send stream as caller.
2760TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002761 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762}
2763
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002764// Test the InsertDtmf on default send stream as callee
2765TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002766 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002767}
2768
2769// Test the InsertDtmf on specified send stream as caller.
2770TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002771 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002772}
2773
2774// Test the InsertDtmf on specified send stream as callee.
2775TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002776 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002777}
2778
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002779TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002780 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002781 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002782 EXPECT_CALL(adm_,
2783 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2784 EXPECT_CALL(adm_,
2785 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2786 EXPECT_CALL(adm_,
2787 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002788
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002789 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2790 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791
solenberg246b8172015-12-08 09:50:23 -08002792 // Nothing set in AudioOptions, so everything should be as default.
2793 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002794 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002795 EXPECT_TRUE(IsHighPassFilterEnabled());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002796 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2797 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002798
2799 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002800 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002802 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002803 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804
2805 // Turn echo cancellation back on, with settings, and make sure
2806 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002807 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2808 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002809 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002810 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002812 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2813 // control.
solenberg76377c52017-02-21 00:54:31 -08002814 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2815 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002816 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002817 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002818
2819 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002820 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2821 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002822 send_parameters_.options.delay_agnostic_aec = false;
2823 send_parameters_.options.extended_filter_aec = false;
2824 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002825 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002826
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002827 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002828 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2829 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002830 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002831 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002832
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002833 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002834 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2835 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002836 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002837 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002838 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002839 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840
2841 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002842 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2843 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002844 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002845 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002846 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002847 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002848
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002849 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002850 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2851 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002852 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002853 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002854 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002855 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2856 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002857 send_parameters_.options.noise_suppression = false;
2858 send_parameters_.options.highpass_filter = false;
2859 send_parameters_.options.typing_detection = false;
2860 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002861 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002862 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863
solenberg1ac56142015-10-13 03:58:19 -07002864 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002865 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2866 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002867 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002868 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002869 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002870 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002872 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002873}
2874
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002875TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002876 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002877 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002878 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002879 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002880 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002881 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002882 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002883 EXPECT_CALL(adm_,
2884 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2885 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2886 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002887 webrtc::AudioProcessing::Config apm_config;
2888 EXPECT_CALL(*apm_, GetConfig())
2889 .Times(10)
2890 .WillRepeatedly(ReturnPointee(&apm_config));
2891 EXPECT_CALL(*apm_, ApplyConfig(_))
2892 .Times(10)
2893 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002894 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002895
kwiberg686a8ef2016-02-26 03:00:35 -08002896 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002897 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002898 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002899 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002900 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002901 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902
2903 // Have to add a stream to make SetSend work.
2904 cricket::StreamParams stream1;
2905 stream1.ssrcs.push_back(1);
2906 channel1->AddSendStream(stream1);
2907 cricket::StreamParams stream2;
2908 stream2.ssrcs.push_back(2);
2909 channel2->AddSendStream(stream2);
2910
2911 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002912 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002913 parameters_options_all.options.echo_cancellation = true;
2914 parameters_options_all.options.auto_gain_control = true;
2915 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2917 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002920 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002921 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002922 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002923 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002924 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002925 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926
2927 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002928 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002929 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002930 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2931 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002932 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002933 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002934 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002936 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002937 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002938 expected_options.echo_cancellation = true;
2939 expected_options.auto_gain_control = true;
2940 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002941 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942
2943 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002944 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002945 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002946 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2947 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002948 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002949 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002952 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002953 expected_options.echo_cancellation = true;
2954 expected_options.auto_gain_control = false;
2955 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002956 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002957
solenberg76377c52017-02-21 00:54:31 -08002958 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2959 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002960 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002961 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002962 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002963 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002964 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002965
solenberg76377c52017-02-21 00:54:31 -08002966 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2967 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002968 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002969 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002970 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002971 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002972 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002973
solenberg76377c52017-02-21 00:54:31 -08002974 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2975 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002976 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002977 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002978 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002979 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002980 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002982 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002983 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2984 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002985 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2986 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002987 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2988 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002989 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002990 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002991 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002992 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002993 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002994 expected_options.echo_cancellation = true;
2995 expected_options.auto_gain_control = false;
2996 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002997 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998}
2999
wu@webrtc.orgde305012013-10-31 15:40:38 +00003000// This test verifies DSCP settings are properly applied on voice media channel.
3001TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003002 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003003 cricket::FakeNetworkInterface network_interface;
3004 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003005 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003006
peahb1c9d1d2017-07-25 15:45:24 -07003007 webrtc::AudioProcessing::Config apm_config;
3008 EXPECT_CALL(*apm_, GetConfig())
3009 .Times(3)
3010 .WillRepeatedly(ReturnPointee(&apm_config));
3011 EXPECT_CALL(*apm_, ApplyConfig(_))
3012 .Times(3)
3013 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003014 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003015
solenbergbc37fc82016-04-04 09:54:44 -07003016 channel.reset(
3017 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003018 channel->SetInterface(&network_interface);
3019 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3020 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3021
3022 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003023 channel.reset(
3024 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003025 channel->SetInterface(&network_interface);
3026 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3027
3028 // Verify that setting the option to false resets the
3029 // DiffServCodePoint.
3030 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003031 channel.reset(
3032 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003033 channel->SetInterface(&network_interface);
3034 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3035 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3036
3037 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003038}
3039
solenberg4bac9c52015-10-09 02:32:53 -07003040TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003041 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003042 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003044 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003045 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003046 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3047 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3048 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003049}
3050
solenberg2100c0b2017-03-01 11:29:29 -08003051TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003052 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003053
3054 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003055 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003056 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3057
3058 // Should remember the volume "2" which will be set on new unsignaled streams,
3059 // and also set the gain to 2 on existing unsignaled streams.
3060 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3061 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3062
3063 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3064 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3065 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3066 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3067 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3068 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3069
3070 // Setting gain with SSRC=0 should affect all unsignaled streams.
3071 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003072 if (kMaxUnsignaledRecvStreams > 1) {
3073 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3074 }
solenberg2100c0b2017-03-01 11:29:29 -08003075 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3076
3077 // Setting gain on an individual stream affects only that.
3078 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003079 if (kMaxUnsignaledRecvStreams > 1) {
3080 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3081 }
solenberg2100c0b2017-03-01 11:29:29 -08003082 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083}
3084
Seth Hampson845e8782018-03-02 11:34:10 -08003085TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003086 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003087 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003088
solenbergff976312016-03-30 23:28:51 -07003089 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003090 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003091 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003092 // Creating two channels to make sure that sync label is set properly for both
3093 // the default voice channel and following ones.
3094 EXPECT_TRUE(channel_->AddRecvStream(sp));
3095 sp.ssrcs[0] += 1;
3096 EXPECT_TRUE(channel_->AddRecvStream(sp));
3097
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003098 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003099 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003100 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003101 << "SyncGroup should be set based on stream id";
3102 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003103 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003104 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003105}
3106
solenberg3a941542015-11-16 07:34:50 -08003107// TODO(solenberg): Remove, once recv streams are configured through Call.
3108// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003109TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003110 // Test that setting the header extensions results in the expected state
3111 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003112 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003113 ssrcs.push_back(223);
3114 ssrcs.push_back(224);
3115
solenbergff976312016-03-30 23:28:51 -07003116 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003117 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003118 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003119 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003120 cricket::StreamParams::CreateLegacy(ssrc)));
3121 }
3122
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003123 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003124 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003125 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003126 EXPECT_NE(nullptr, s);
3127 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3128 }
3129
3130 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003131 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003132 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003133 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003134 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003135 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003136 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003137 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003138 EXPECT_NE(nullptr, s);
3139 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003140 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3141 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003142 for (const auto& s_ext : s_exts) {
3143 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003144 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003145 }
3146 }
3147 }
3148 }
3149
3150 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003151 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003152 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003153 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003154 EXPECT_NE(nullptr, s);
3155 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3156 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003157}
3158
3159TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3160 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003161 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003162 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003163 static const unsigned char kRtcp[] = {
3164 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3165 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3168 };
jbaucheec21bd2016-03-20 06:15:43 -07003169 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003170
solenbergff976312016-03-30 23:28:51 -07003171 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003172 cricket::WebRtcVoiceMediaChannel* media_channel =
3173 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003174 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003175 EXPECT_TRUE(media_channel->AddRecvStream(
3176 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3177
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003178 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003179 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003180 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003181 EXPECT_EQ(0, s->received_packets());
3182 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3183 EXPECT_EQ(1, s->received_packets());
3184 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3185 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003186}
Minyue2013aec2015-05-13 14:14:42 +02003187
solenberg0a617e22015-10-20 15:49:38 -07003188// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003189// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003190TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003191 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003192 EXPECT_TRUE(AddRecvStream(kSsrcY));
3193 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003194 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003195 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3196 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3197 EXPECT_TRUE(AddRecvStream(kSsrcW));
3198 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003199}
3200
solenberg7602aab2016-11-14 11:30:07 -08003201TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3202 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003203 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003204 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003205 cricket::StreamParams::CreateLegacy(kSsrcY)));
3206 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3207 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3208 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003209 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003210 cricket::StreamParams::CreateLegacy(kSsrcW)));
3211 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3212 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003213}
stefan658910c2015-09-03 05:48:32 -07003214
deadbeef884f5852016-01-15 09:20:04 -08003215TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003216 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003217 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3218 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003219
3220 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003221 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3222 EXPECT_TRUE(AddRecvStream(kSsrcX));
3223 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003224
3225 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003226 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3227 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003228
3229 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003230 channel_->SetRawAudioSink(kSsrcX, nullptr);
3231 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003232}
3233
solenberg2100c0b2017-03-01 11:29:29 -08003234TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003235 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003236 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3237 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003238 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3239 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003240
3241 // Should be able to set a default sink even when no stream exists.
3242 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3243
solenberg2100c0b2017-03-01 11:29:29 -08003244 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3245 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003246 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003247 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003248
3249 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003250 channel_->SetRawAudioSink(kSsrc0, nullptr);
3251 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003252
3253 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003254 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3255 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003256
3257 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003258 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003259 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003260 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3261
3262 // Spawn another unsignaled stream - it should be assigned the default sink
3263 // and the previous unsignaled stream should lose it.
3264 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3265 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3266 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3267 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003268 if (kMaxUnsignaledRecvStreams > 1) {
3269 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3270 }
solenberg2100c0b2017-03-01 11:29:29 -08003271 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3272
3273 // Reset the default sink - the second unsignaled stream should lose it.
3274 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003275 if (kMaxUnsignaledRecvStreams > 1) {
3276 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3277 }
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3279
3280 // Try setting the default sink while two streams exists.
3281 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003282 if (kMaxUnsignaledRecvStreams > 1) {
3283 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3284 }
solenberg2100c0b2017-03-01 11:29:29 -08003285 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3286
3287 // Try setting the sink for the first unsignaled stream using its known SSRC.
3288 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003289 if (kMaxUnsignaledRecvStreams > 1) {
3290 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3291 }
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003293 if (kMaxUnsignaledRecvStreams > 1) {
3294 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3295 }
deadbeef884f5852016-01-15 09:20:04 -08003296}
3297
skvlad7a43d252016-03-22 15:32:27 -07003298// Test that, just like the video channel, the voice channel communicates the
3299// network state to the call.
3300TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003301 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003302
3303 EXPECT_EQ(webrtc::kNetworkUp,
3304 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3305 EXPECT_EQ(webrtc::kNetworkUp,
3306 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3307
3308 channel_->OnReadyToSend(false);
3309 EXPECT_EQ(webrtc::kNetworkDown,
3310 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3311 EXPECT_EQ(webrtc::kNetworkUp,
3312 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3313
3314 channel_->OnReadyToSend(true);
3315 EXPECT_EQ(webrtc::kNetworkUp,
3316 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3317 EXPECT_EQ(webrtc::kNetworkUp,
3318 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3319}
3320
aleloi18e0b672016-10-04 02:45:47 -07003321// Test that playout is still started after changing parameters
3322TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3323 SetupRecvStream();
3324 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003325 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003326
3327 // Changing RTP header extensions will recreate the AudioReceiveStream.
3328 cricket::AudioRecvParameters parameters;
3329 parameters.extensions.push_back(
3330 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3331 channel_->SetRecvParameters(parameters);
3332
solenberg2100c0b2017-03-01 11:29:29 -08003333 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003334}
3335
Zhi Huangfa266ef2017-12-13 10:27:46 -08003336// Tests when GetSources is called with non-existing ssrc, it will return an
3337// empty list of RtpSource without crashing.
3338TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3339 // Setup an recv stream with |kSsrcX|.
3340 SetupRecvStream();
3341 cricket::WebRtcVoiceMediaChannel* media_channel =
3342 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3343 // Call GetSources with |kSsrcY| which doesn't exist.
3344 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3345 EXPECT_EQ(0u, sources.size());
3346}
3347
stefan658910c2015-09-03 05:48:32 -07003348// Tests that the library initializes and shuts down properly.
3349TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003350 // If the VoiceEngine wants to gather available codecs early, that's fine but
3351 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003352 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003353 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003354 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003355 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003356 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003357 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003358 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003359 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003360 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003361 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003362 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3363 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003364 EXPECT_TRUE(channel != nullptr);
3365 delete channel;
solenbergff976312016-03-30 23:28:51 -07003366}
stefan658910c2015-09-03 05:48:32 -07003367
solenbergff976312016-03-30 23:28:51 -07003368// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003369TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3370 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003371 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003372 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003373 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003374 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003375 {
peaha9cc40b2017-06-29 08:32:09 -07003376 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003377 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003378 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003379 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003380 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003381 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003382 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003383 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003384 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003385 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3386 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3387 EXPECT_TRUE(channel != nullptr);
3388 delete channel;
3389 }
stefan658910c2015-09-03 05:48:32 -07003390}
3391
ossu20a4b3f2017-04-27 02:08:52 -07003392// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3393TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003394 // TODO(ossu): Why are the payload types of codecs with non-static payload
3395 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003396 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003397 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003398 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003399 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003400 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003401 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003402 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003403 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003404 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3405 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3406 (clockrate == 0 || codec.clockrate == clockrate);
3407 };
3408 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003409 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003410 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003411 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003412 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003413 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003414 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003415 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003416 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003417 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003418 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003419 EXPECT_EQ(126, codec.id);
3420 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3421 // Remove these checks once both send and receive side assigns payload types
3422 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003423 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003424 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003425 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003426 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003427 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003428 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003429 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003430 EXPECT_EQ(111, codec.id);
3431 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3432 EXPECT_EQ("10", codec.params.find("minptime")->second);
3433 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3434 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003435 }
3436 }
stefan658910c2015-09-03 05:48:32 -07003437}
3438
3439// Tests that VoE supports at least 32 channels
3440TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003441 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003442 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003443 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003444 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003445 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003446 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003447 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003448 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003449 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003450 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003451
3452 cricket::VoiceMediaChannel* channels[32];
3453 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003454 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003455 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3456 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003457 if (!channel)
3458 break;
stefan658910c2015-09-03 05:48:32 -07003459 channels[num_channels++] = channel;
3460 }
3461
tfarina5237aaf2015-11-10 23:44:30 -08003462 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003463 EXPECT_EQ(expected, num_channels);
3464
3465 while (num_channels > 0) {
3466 delete channels[--num_channels];
3467 }
stefan658910c2015-09-03 05:48:32 -07003468}
3469
3470// Test that we set our preferred codecs properly.
3471TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003472 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3473 // - Check that our builtin codecs are usable by Channel.
3474 // - The codecs provided by the engine is usable by Channel.
3475 // It does not check that the codecs in the RecvParameters are actually
3476 // what we sent in - though it's probably reasonable to expect so, if
3477 // SetRecvParameters returns true.
3478 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003479 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003480 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003481 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003482 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003483 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003484 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003485 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003486 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003487 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003488 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003489 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3490 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003491 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003492 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003493 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003494}
ossu9def8002017-02-09 05:14:32 -08003495
3496TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3497 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003498 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3499 {48000, 2, 16000, 10000, 20000}};
3500 spec1.info.allow_comfort_noise = false;
3501 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003502 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003503 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3504 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003505 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003506 specs.push_back(webrtc::AudioCodecSpec{
3507 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3508 {16000, 1, 13300}});
3509 specs.push_back(
3510 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3511 specs.push_back(
3512 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003513
ossueb1fde42017-05-02 06:46:30 -07003514 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3515 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3516 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003517 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003518 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003519 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003520 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003521
peaha9cc40b2017-06-29 08:32:09 -07003522 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003523 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003524 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003525 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003526 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003527 auto codecs = engine.recv_codecs();
3528 EXPECT_EQ(11, codecs.size());
3529
3530 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3531 // check the actual values safely, to provide better test results.
3532 auto get_codec =
3533 [&codecs](size_t index) -> const cricket::AudioCodec& {
3534 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3535 if (codecs.size() > index)
3536 return codecs[index];
3537 return missing_codec;
3538 };
3539
3540 // Ensure the general codecs are generated first and in order.
3541 for (size_t i = 0; i != specs.size(); ++i) {
3542 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3543 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3544 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3545 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3546 }
3547
3548 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003549 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003550 auto find_codec =
3551 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3552 for (size_t i = 0; i != codecs.size(); ++i) {
3553 const cricket::AudioCodec& codec = codecs[i];
3554 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3555 codec.clockrate == format.clockrate_hz &&
3556 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003557 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003558 }
3559 }
3560 return -1;
3561 };
3562
3563 // Ensure all supplementary codecs are generated last. Their internal ordering
3564 // is not important.
3565 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3566 const int num_specs = static_cast<int>(specs.size());
3567 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3568 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3569 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3570 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3571 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3572 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3573 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3574}