blob: bb816eed11827f2c0cdc62991643ebdb09835f83 [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);
Yves Gerey665174f2018-06-19 15:03:05 +020057const cricket::AudioCodec kTelephoneEventCodec1(106,
58 "telephone-event",
59 8000,
60 0,
61 1);
62const cricket::AudioCodec kTelephoneEventCodec2(107,
63 "telephone-event",
64 32000,
65 0,
66 1);
solenberg2779bab2016-11-17 04:45:19 -080067
solenberg2100c0b2017-03-01 11:29:29 -080068const uint32_t kSsrc0 = 0;
69const uint32_t kSsrc1 = 1;
70const uint32_t kSsrcX = 0x99;
71const uint32_t kSsrcY = 0x17;
72const uint32_t kSsrcZ = 0x42;
73const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020074const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075
solenberg971cab02016-06-14 10:02:41 -070076constexpr int kRtpHistoryMs = 5000;
77
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010078constexpr webrtc::GainControl::Mode kDefaultAgcMode =
79#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
80 webrtc::GainControl::kFixedDigital;
81#else
82 webrtc::GainControl::kAdaptiveAnalog;
83#endif
84
85constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
86 webrtc::NoiseSuppression::kHigh;
87
solenberg9a5f032222017-03-15 06:14:12 -070088void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
89 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010090
91 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010092 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010093 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010094 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070095#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020096 EXPECT_CALL(
97 *adm, SetPlayoutDevice(
98 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
99 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
100 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700101#else
102 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
103#endif // #if defined(WEBRTC_WIN)
104 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
105 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
106 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100107#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200108 EXPECT_CALL(
109 *adm, SetRecordingDevice(
110 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
111 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
112 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113#else
114 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
115#endif // #if defined(WEBRTC_WIN)
116 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
117 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
118 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700119 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100122
123 // Teardown.
124 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
125 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
127 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200128 EXPECT_CALL(*adm, Release())
129 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100130 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700131}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200132} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133
solenbergff976312016-03-30 23:28:51 -0700134// Tests that our stub library "works".
135TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700136 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700137 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700138 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
139 new rtc::RefCountedObject<
140 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700141 webrtc::AudioProcessing::Config apm_config;
142 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
143 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700144 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700146 {
ossuc54071d2016-08-17 02:45:41 -0700147 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700148 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100149 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700150 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700151 }
solenbergff976312016-03-30 23:28:51 -0700152}
153
deadbeef884f5852016-01-15 09:20:04 -0800154class FakeAudioSink : public webrtc::AudioSinkInterface {
155 public:
156 void OnData(const Data& audio) override {}
157};
158
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800159class FakeAudioSource : public cricket::AudioSource {
160 void SetSink(Sink* sink) override {}
161};
162
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163class WebRtcVoiceEngineTestFake : public testing::Test {
164 public:
stefanba4c0e42016-02-04 04:12:24 -0800165 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
166
167 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700168 : apm_(new rtc::RefCountedObject<
169 StrictMock<webrtc::test::MockAudioProcessing>>()),
170 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700171 apm_ns_(*apm_->noise_suppression()),
172 apm_vd_(*apm_->voice_detection()),
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100173 call_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700174 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800175 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700176 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800177 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700178 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
179 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700180 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700181 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800182 // Default Options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100183 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800184 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100185 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
186 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800189 // Init does not overwrite default AGC config.
190 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
191 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
192 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800193 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
194 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700195 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800196 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700197 // factories. Those tests should probably be moved elsewhere.
198 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
199 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100200 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100201 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200207 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800208 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 }
solenberg8189b022016-06-14 12:13:00 -0700210
solenbergff976312016-03-30 23:28:51 -0700211 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700212 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700213 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
214 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200215 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000216 }
solenberg8189b022016-06-14 12:13:00 -0700217
solenbergff976312016-03-30 23:28:51 -0700218 bool SetupRecvStream() {
219 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700220 return false;
221 }
solenberg2100c0b2017-03-01 11:29:29 -0800222 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700223 }
solenberg8189b022016-06-14 12:13:00 -0700224
solenbergff976312016-03-30 23:28:51 -0700225 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200226 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
227 }
228
229 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700230 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000231 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
Florent Castellidacec712018-05-24 16:24:21 +0200233 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800234 return false;
235 }
peaha9cc40b2017-06-29 08:32:09 -0700236 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800237 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 }
solenberg8189b022016-06-14 12:13:00 -0700239
240 bool AddRecvStream(uint32_t ssrc) {
241 EXPECT_TRUE(channel_);
242 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
243 }
244
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000245 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700246 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700247 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800248 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
249 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700250 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800251 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000252 }
solenberg8189b022016-06-14 12:13:00 -0700253
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700255 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000256 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 }
solenberg8189b022016-06-14 12:13:00 -0700258
Yves Gerey665174f2018-06-19 15:03:05 +0200259 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100261 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
262 const auto* send_stream = call_.GetAudioSendStream(ssrc);
263 EXPECT_TRUE(send_stream);
264 return *send_stream;
265 }
266
deadbeef884f5852016-01-15 09:20:04 -0800267 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
268 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
269 EXPECT_TRUE(recv_stream);
270 return *recv_stream;
271 }
272
solenberg3a941542015-11-16 07:34:50 -0800273 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800274 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800275 }
276
solenberg7add0582015-11-20 09:59:34 -0800277 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800278 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800279 }
280
solenberg059fb442016-10-26 05:12:24 -0700281 void SetSend(bool enable) {
282 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700283 if (enable) {
284 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
285 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700287 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700288 }
solenberg059fb442016-10-26 05:12:24 -0700289 channel_->SetSend(enable);
290 }
291
292 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700293 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700294 ASSERT_TRUE(channel_);
295 EXPECT_TRUE(channel_->SetSendParameters(params));
296 }
297
Yves Gerey665174f2018-06-19 15:03:05 +0200298 void SetAudioSend(uint32_t ssrc,
299 bool enable,
300 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700301 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700302 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700303 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700304 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700305 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700306 }
307 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700308 }
309
Yves Gerey665174f2018-06-19 15:03:05 +0200310 void TestInsertDtmf(uint32_t ssrc,
311 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800312 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700313 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700315 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200317 EXPECT_TRUE(
318 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000319 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700322 SetSendParameters(send_parameters_);
323 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800325 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800326 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700327 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329
330 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700331 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800332 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200333 EXPECT_TRUE(
334 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000335 }
336
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100340 // Test send.
341 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800342 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100343 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800344 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800345 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800346 EXPECT_EQ(codec.id, telephone_event.payload_type);
347 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100348 EXPECT_EQ(2, telephone_event.event_code);
349 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 }
351
352 // Test that send bandwidth is set correctly.
353 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000354 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
355 // |expected_result| is the expected result from SetMaxSendBandwidth().
356 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700357 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
358 int max_bitrate,
359 bool expected_result,
360 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200361 cricket::AudioSendParameters parameters;
362 parameters.codecs.push_back(codec);
363 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700364 if (expected_result) {
365 SetSendParameters(parameters);
366 } else {
367 EXPECT_FALSE(channel_->SetSendParameters(parameters));
368 }
solenberg2100c0b2017-03-01 11:29:29 -0800369 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370 }
371
skvlade0d46372016-04-07 22:59:22 -0700372 // Sets the per-stream maximum bitrate limit for the specified SSRC.
373 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700374 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700375 EXPECT_EQ(1UL, parameters.encodings.size());
376
Oskar Sundbom78807582017-11-16 11:09:55 +0100377 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800378 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700379 }
380
solenberg059fb442016-10-26 05:12:24 -0700381 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700382 cricket::AudioSendParameters send_parameters;
383 send_parameters.codecs.push_back(codec);
384 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700385 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700386 }
387
ossu20a4b3f2017-04-27 02:08:52 -0700388 void CheckSendCodecBitrate(int32_t ssrc,
389 const char expected_name[],
390 int expected_bitrate) {
391 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
392 EXPECT_EQ(expected_name, spec->format.name);
393 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700394 }
395
Danil Chapovalov00c71832018-06-15 15:58:38 +0200396 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700397 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700398 }
399
Danil Chapovalov00c71832018-06-15 15:58:38 +0200400 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
401 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700402 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
403 }
404
skvlade0d46372016-04-07 22:59:22 -0700405 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
406 int global_max,
407 int stream_max,
408 bool expected_result,
409 int expected_codec_bitrate) {
410 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800411 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700412
413 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700414 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800415 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700416
417 // Verify that reading back the parameters gives results
418 // consistent with the Set() result.
419 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800420 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700421 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
422 EXPECT_EQ(expected_result ? stream_max : -1,
423 resulting_parameters.encodings[0].max_bitrate_bps);
424
425 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800426 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700427 }
428
stefan13f1a0a2016-11-30 07:22:58 -0800429 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
430 int expected_min_bitrate_bps,
431 const char* start_bitrate_kbps,
432 int expected_start_bitrate_bps,
433 const char* max_bitrate_kbps,
434 int expected_max_bitrate_bps) {
435 EXPECT_TRUE(SetupSendStream());
436 auto& codecs = send_parameters_.codecs;
437 codecs.clear();
438 codecs.push_back(kOpusCodec);
439 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
440 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
441 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100442 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
443 SetSdpBitrateParameters(
444 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
445 expected_min_bitrate_bps),
446 Field(&BitrateConstraints::start_bitrate_bps,
447 expected_start_bitrate_bps),
448 Field(&BitrateConstraints::max_bitrate_bps,
449 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800450
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100451 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800452 }
453
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000454 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700455 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000456
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000457 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800458 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000459
460 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700461 send_parameters_.extensions.push_back(
462 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700463 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800464 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000465
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000466 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200467 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700468 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800469 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000471 // Ensure extension is set properly.
472 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700473 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700474 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800475 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
476 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
477 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000478
solenberg7add0582015-11-20 09:59:34 -0800479 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200480 EXPECT_TRUE(
481 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800482 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
483 call_.GetAudioSendStream(kSsrcY));
484 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
485 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
486 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487
488 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200489 send_parameters_.codecs.push_back(kPcmuCodec);
490 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700491 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
493 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494 }
495
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000496 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700497 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000498
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800500 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000501
502 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700503 recv_parameters_.extensions.push_back(
504 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800505 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800506 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000507
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000508 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800509 recv_parameters_.extensions.clear();
510 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000513 // Ensure extension is set properly.
514 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700515 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800516 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000520
solenberg7add0582015-11-20 09:59:34 -0800521 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800522 EXPECT_TRUE(AddRecvStream(kSsrcY));
523 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
524 call_.GetAudioReceiveStream(kSsrcY));
525 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
526 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
527 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000528
529 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800530 recv_parameters_.extensions.clear();
531 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800532 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
533 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000534 }
535
solenberg85a04962015-10-27 03:35:21 -0700536 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
537 webrtc::AudioSendStream::Stats stats;
538 stats.local_ssrc = 12;
539 stats.bytes_sent = 345;
540 stats.packets_sent = 678;
541 stats.packets_lost = 9012;
542 stats.fraction_lost = 34.56f;
543 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100544 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700545 stats.ext_seqnum = 789;
546 stats.jitter_ms = 12;
547 stats.rtt_ms = 345;
548 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100549 stats.apm_statistics.delay_median_ms = 234;
550 stats.apm_statistics.delay_standard_deviation_ms = 567;
551 stats.apm_statistics.echo_return_loss = 890;
552 stats.apm_statistics.echo_return_loss_enhancement = 1234;
553 stats.apm_statistics.residual_echo_likelihood = 0.432f;
554 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100555 stats.ana_statistics.bitrate_action_counter = 321;
556 stats.ana_statistics.channel_action_counter = 432;
557 stats.ana_statistics.dtx_action_counter = 543;
558 stats.ana_statistics.fec_action_counter = 654;
559 stats.ana_statistics.frame_length_increase_counter = 765;
560 stats.ana_statistics.frame_length_decrease_counter = 876;
561 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700562 stats.typing_noise_detected = true;
563 return stats;
564 }
565 void SetAudioSendStreamStats() {
566 for (auto* s : call_.GetAudioSendStreams()) {
567 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200568 }
solenberg85a04962015-10-27 03:35:21 -0700569 }
solenberg566ef242015-11-06 15:34:49 -0800570 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
571 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700572 const auto stats = GetAudioSendStreamStats();
573 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
574 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
575 EXPECT_EQ(info.packets_sent, stats.packets_sent);
576 EXPECT_EQ(info.packets_lost, stats.packets_lost);
577 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
578 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800579 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700580 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
581 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
582 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
583 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100584 EXPECT_EQ(info.apm_statistics.delay_median_ms,
585 stats.apm_statistics.delay_median_ms);
586 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
587 stats.apm_statistics.delay_standard_deviation_ms);
588 EXPECT_EQ(info.apm_statistics.echo_return_loss,
589 stats.apm_statistics.echo_return_loss);
590 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
591 stats.apm_statistics.echo_return_loss_enhancement);
592 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
593 stats.apm_statistics.residual_echo_likelihood);
594 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
595 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700596 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
597 stats.ana_statistics.bitrate_action_counter);
598 EXPECT_EQ(info.ana_statistics.channel_action_counter,
599 stats.ana_statistics.channel_action_counter);
600 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
601 stats.ana_statistics.dtx_action_counter);
602 EXPECT_EQ(info.ana_statistics.fec_action_counter,
603 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700604 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
605 stats.ana_statistics.frame_length_increase_counter);
606 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
607 stats.ana_statistics.frame_length_decrease_counter);
608 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
609 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800610 EXPECT_EQ(info.typing_noise_detected,
611 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700612 }
613
614 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
615 webrtc::AudioReceiveStream::Stats stats;
616 stats.remote_ssrc = 123;
617 stats.bytes_rcvd = 456;
618 stats.packets_rcvd = 768;
619 stats.packets_lost = 101;
620 stats.fraction_lost = 23.45f;
621 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100622 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700623 stats.ext_seqnum = 678;
624 stats.jitter_ms = 901;
625 stats.jitter_buffer_ms = 234;
626 stats.jitter_buffer_preferred_ms = 567;
627 stats.delay_estimate_ms = 890;
628 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700629 stats.total_samples_received = 5678901;
630 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200631 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200632 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700633 stats.expand_rate = 5.67f;
634 stats.speech_expand_rate = 8.90f;
635 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200636 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700637 stats.accelerate_rate = 4.56f;
638 stats.preemptive_expand_rate = 7.89f;
639 stats.decoding_calls_to_silence_generator = 12;
640 stats.decoding_calls_to_neteq = 345;
641 stats.decoding_normal = 67890;
642 stats.decoding_plc = 1234;
643 stats.decoding_cng = 5678;
644 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700645 stats.decoding_muted_output = 3456;
646 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200647 return stats;
648 }
649 void SetAudioReceiveStreamStats() {
650 for (auto* s : call_.GetAudioReceiveStreams()) {
651 s->SetStats(GetAudioReceiveStreamStats());
652 }
653 }
654 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700655 const auto stats = GetAudioReceiveStreamStats();
656 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
657 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200658 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
659 stats.packets_rcvd);
660 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
661 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700662 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
663 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800664 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200665 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
666 stats.ext_seqnum);
667 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
668 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
669 stats.jitter_buffer_ms);
670 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700671 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200672 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
673 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700674 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700675 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
676 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200677 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200678 EXPECT_EQ(info.jitter_buffer_delay_seconds,
679 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700680 EXPECT_EQ(info.expand_rate, stats.expand_rate);
681 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
682 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200683 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700684 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
685 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200686 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700687 stats.decoding_calls_to_silence_generator);
688 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
689 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
690 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
691 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
692 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700693 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700694 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200695 }
hbos1acfbd22016-11-17 23:43:29 -0800696 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
697 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
698 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
699 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
700 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
701 codec.ToCodecParameters());
702 }
703 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
704 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
705 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
706 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
707 codec.ToCodecParameters());
708 }
709 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200710
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200711 bool IsEchoCancellationEnabled() {
712 return engine_->GetApmConfigForTest().echo_canceller.enabled;
713 }
714
peah8271d042016-11-22 07:24:52 -0800715 bool IsHighPassFilterEnabled() {
716 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
717 }
718
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700720 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700721 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800722 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800723 webrtc::test::MockNoiseSuppression& apm_ns_;
724 webrtc::test::MockVoiceDetection& apm_vd_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200725 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700726 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700727 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200728 cricket::AudioSendParameters send_parameters_;
729 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800730 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700731 webrtc::AudioProcessing::Config apm_config_;
732
stefanba4c0e42016-02-04 04:12:24 -0800733 private:
734 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735};
736
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737// Tests that we can create and destroy a channel.
738TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700739 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740}
741
solenberg31fec402016-05-06 02:13:12 -0700742// Test that we can add a send stream and that it has the correct defaults.
743TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
744 EXPECT_TRUE(SetupChannel());
745 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800746 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
747 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
748 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700749 EXPECT_EQ("", config.rtp.c_name);
750 EXPECT_EQ(0u, config.rtp.extensions.size());
751 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
752 config.send_transport);
753}
754
755// Test that we can add a receive stream and that it has the correct defaults.
756TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
757 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800758 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700759 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800760 GetRecvStreamConfig(kSsrcX);
761 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700762 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
763 EXPECT_FALSE(config.rtp.transport_cc);
764 EXPECT_EQ(0u, config.rtp.extensions.size());
765 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
766 config.rtcp_send_transport);
767 EXPECT_EQ("", config.sync_group);
768}
769
stefanba4c0e42016-02-04 04:12:24 -0800770TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700771 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800772 bool opus_found = false;
773 for (cricket::AudioCodec codec : codecs) {
774 if (codec.name == "opus") {
775 EXPECT_TRUE(HasTransportCc(codec));
776 opus_found = true;
777 }
778 }
779 EXPECT_TRUE(opus_found);
780}
781
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782// Test that we set our inbound codecs properly, including changing PT.
783TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700784 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 cricket::AudioRecvParameters parameters;
786 parameters.codecs.push_back(kIsacCodec);
787 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800788 parameters.codecs.push_back(kTelephoneEventCodec1);
789 parameters.codecs.push_back(kTelephoneEventCodec2);
790 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 parameters.codecs[2].id = 126;
792 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800793 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700794 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
795 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
796 {{0, {"PCMU", 8000, 1}},
797 {106, {"ISAC", 16000, 1}},
798 {126, {"telephone-event", 8000, 1}},
799 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800}
801
802// Test that we fail to set an unknown inbound codec.
803TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700804 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200805 cricket::AudioRecvParameters parameters;
806 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700807 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200808 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that we fail if we have duplicate types in the inbound list.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kCn16000Codec);
817 parameters.codecs[1].id = kIsacCodec.id;
818 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that we can decode OPUS without stereo parameters.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
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 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800829 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700830 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
831 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
832 {{0, {"PCMU", 8000, 1}},
833 {103, {"ISAC", 16000, 1}},
834 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835}
836
837// Test that we can decode OPUS with stereo = 0.
838TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700839 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 cricket::AudioRecvParameters parameters;
841 parameters.codecs.push_back(kIsacCodec);
842 parameters.codecs.push_back(kPcmuCodec);
843 parameters.codecs.push_back(kOpusCodec);
844 parameters.codecs[2].params["stereo"] = "0";
845 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800846 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700847 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
848 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
849 {{0, {"PCMU", 8000, 1}},
850 {103, {"ISAC", 16000, 1}},
851 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852}
853
854// Test that we can decode OPUS with stereo = 1.
855TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700856 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 cricket::AudioRecvParameters parameters;
858 parameters.codecs.push_back(kIsacCodec);
859 parameters.codecs.push_back(kPcmuCodec);
860 parameters.codecs.push_back(kOpusCodec);
861 parameters.codecs[2].params["stereo"] = "1";
862 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800863 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700864 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
865 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
866 {{0, {"PCMU", 8000, 1}},
867 {103, {"ISAC", 16000, 1}},
868 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869}
870
871// Test that changes to recv codecs are applied to all streams.
872TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700873 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200874 cricket::AudioRecvParameters parameters;
875 parameters.codecs.push_back(kIsacCodec);
876 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800877 parameters.codecs.push_back(kTelephoneEventCodec1);
878 parameters.codecs.push_back(kTelephoneEventCodec2);
879 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200880 parameters.codecs[2].id = 126;
881 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700882 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
883 EXPECT_TRUE(AddRecvStream(ssrc));
884 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
885 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
886 {{0, {"PCMU", 8000, 1}},
887 {106, {"ISAC", 16000, 1}},
888 {126, {"telephone-event", 8000, 1}},
889 {107, {"telephone-event", 32000, 1}}})));
890 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891}
892
893TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700894 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200895 cricket::AudioRecvParameters parameters;
896 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800897 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
solenberg2100c0b2017-03-01 11:29:29 -0800900 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200901 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800902 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903}
904
905// Test that we can apply the same set of codecs again while playing.
906TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700907 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 cricket::AudioRecvParameters parameters;
909 parameters.codecs.push_back(kIsacCodec);
910 parameters.codecs.push_back(kCn16000Codec);
911 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700912 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
deadbeefcb383672017-04-26 16:28:42 -0700915 // Remapping a payload type to a different codec should fail.
916 parameters.codecs[0] = kOpusCodec;
917 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800919 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
922// Test that we can add a codec while playing.
923TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700924 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200925 cricket::AudioRecvParameters parameters;
926 parameters.codecs.push_back(kIsacCodec);
927 parameters.codecs.push_back(kCn16000Codec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700929 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 parameters.codecs.push_back(kOpusCodec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800933 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934}
935
deadbeefcb383672017-04-26 16:28:42 -0700936// Test that we accept adding the same codec with a different payload type.
937// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
938TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
939 EXPECT_TRUE(SetupRecvStream());
940 cricket::AudioRecvParameters parameters;
941 parameters.codecs.push_back(kIsacCodec);
942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
943
944 ++parameters.codecs[0].id;
945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
946}
947
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700949 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951 // Test that when autobw is enabled, bitrate is kept as the default
952 // value. autobw is enabled for the following tests because the target
953 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
955 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700956 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
958 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960
ossu20a4b3f2017-04-27 02:08:52 -0700961 // opus, default bitrate == 32000 in mono.
962 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000965TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700966 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700969 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
970 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700971 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700974 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
975 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
976 // Rates above the max (510000) should be capped.
977 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978}
979
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700981 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000982
983 // Test that we can only set a maximum bitrate for a fixed-rate codec
984 // if it's bigger than the fixed rate.
985
986 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700987 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
988 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
989 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
991 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000994}
995
996TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700997 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200998 const int kDesiredBitrate = 128000;
999 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001000 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001001 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001002 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001003
Yves Gerey665174f2018-06-19 15:03:05 +02001004 EXPECT_TRUE(
1005 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001006
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001008}
1009
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001010// Test that bitrate cannot be set for CBR codecs.
1011// Bitrate is ignored if it is higher than the fixed bitrate.
1012// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001013TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001014 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015
1016 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001017 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001018 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001019
1020 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001021 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001022 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001023
1024 send_parameters_.max_bandwidth_bps = 128;
1025 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001026 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027}
1028
skvlade0d46372016-04-07 22:59:22 -07001029// Test that the per-stream bitrate limit and the global
1030// bitrate limit both apply.
1031TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1032 EXPECT_TRUE(SetupSendStream());
1033
ossu20a4b3f2017-04-27 02:08:52 -07001034 // opus, default bitrate == 32000.
1035 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001036 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1037 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1038 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1039
1040 // CBR codecs allow both maximums to exceed the bitrate.
1041 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1042 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1043 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1044 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1045
1046 // CBR codecs don't allow per stream maximums to be too low.
1047 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1049}
1050
1051// Test that an attempt to set RtpParameters for a stream that does not exist
1052// fails.
1053TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1054 EXPECT_TRUE(SetupChannel());
1055 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001056 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001057 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001058
1059 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001060 EXPECT_FALSE(
1061 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001062}
1063
1064TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001065 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001066 // This test verifies that setting RtpParameters succeeds only if
1067 // the structure contains exactly one encoding.
1068 // TODO(skvlad): Update this test when we start supporting setting parameters
1069 // for each encoding individually.
1070
1071 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001072 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001073 // Two or more encodings should result in failure.
1074 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001075 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001076 // Zero encodings should also fail.
1077 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001078 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001079}
1080
1081// Changing the SSRC through RtpParameters is not allowed.
1082TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1083 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001084 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001085 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001086 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001087}
1088
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001089// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001090// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1092 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001093 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001096 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001097 ASSERT_EQ(1u, parameters.encodings.size());
1098 ASSERT_TRUE(parameters.encodings[0].active);
1099 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001100 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001101 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001102
1103 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001104 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001106 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001107 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001109}
1110
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001111// Test that SetRtpSendParameters configures the correct encoding channel for
1112// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001113TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1114 SetupForMultiSendStream();
1115 // Create send streams.
1116 for (uint32_t ssrc : kSsrcs4) {
1117 EXPECT_TRUE(
1118 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1119 }
1120 // Configure one stream to be limited by the stream config, another to be
1121 // limited by the global max, and the third one with no per-stream limit
1122 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001123 SetGlobalMaxBitrate(kOpusCodec, 32000);
1124 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1125 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1127
ossu20a4b3f2017-04-27 02:08:52 -07001128 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1129 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1130 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001131
1132 // Remove the global cap; the streams should switch to their respective
1133 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001134 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001135 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1136 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1137 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001138}
1139
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140// Test that GetRtpSendParameters returns the currently configured codecs.
1141TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142 EXPECT_TRUE(SetupSendStream());
1143 cricket::AudioSendParameters parameters;
1144 parameters.codecs.push_back(kIsacCodec);
1145 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001146 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147
solenberg2100c0b2017-03-01 11:29:29 -08001148 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1151 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152}
1153
Florent Castellidacec712018-05-24 16:24:21 +02001154// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1155TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1156 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1157 params.cname = "rtcpcname";
1158 EXPECT_TRUE(SetupSendStream(params));
1159
1160 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1161 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1162}
1163
Florent Castelliabe301f2018-06-12 18:33:49 +02001164TEST_F(WebRtcVoiceEngineTestFake,
1165 DetectRtpSendParameterHeaderExtensionsChange) {
1166 EXPECT_TRUE(SetupSendStream());
1167
1168 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1169 rtp_parameters.header_extensions.emplace_back();
1170
1171 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1172
1173 webrtc::RTCError result =
1174 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1175 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1176}
1177
deadbeefcb443432016-12-12 11:12:36 -08001178// Test that GetRtpSendParameters returns an SSRC.
1179TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1180 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001181 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001182 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001183 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001184}
1185
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001186// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001187TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001188 EXPECT_TRUE(SetupSendStream());
1189 cricket::AudioSendParameters parameters;
1190 parameters.codecs.push_back(kIsacCodec);
1191 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001192 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001193
solenberg2100c0b2017-03-01 11:29:29 -08001194 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001195
1196 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001197 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001198
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001200 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1201 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001202}
1203
minyuececec102017-03-27 13:04:25 -07001204// Test that max_bitrate_bps in send stream config gets updated correctly when
1205// SetRtpSendParameters is called.
1206TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1207 webrtc::test::ScopedFieldTrials override_field_trials(
1208 "WebRTC-Audio-SendSideBwe/Enabled/");
1209 EXPECT_TRUE(SetupSendStream());
1210 cricket::AudioSendParameters send_parameters;
1211 send_parameters.codecs.push_back(kOpusCodec);
1212 SetSendParameters(send_parameters);
1213
1214 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1215 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1216 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1217
1218 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001219 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001220 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001221
1222 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1223 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1224}
1225
Seth Hampson24722b32017-12-22 09:36:42 -08001226// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1227// a value <= 0, setting the parameters returns false.
1228TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1229 EXPECT_TRUE(SetupSendStream());
1230 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1231 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1232 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1233 rtp_parameters.encodings[0].bitrate_priority);
1234
1235 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001236 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001237 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001238 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001239}
1240
1241// Test that the bitrate_priority in the send stream config gets updated when
1242// SetRtpSendParameters is set for the VoiceMediaChannel.
1243TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1244 EXPECT_TRUE(SetupSendStream());
1245 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1246
1247 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1248 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1249 rtp_parameters.encodings[0].bitrate_priority);
1250 double new_bitrate_priority = 2.0;
1251 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001252 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001253
1254 // The priority should get set for both the audio channel's rtp parameters
1255 // and the audio send stream's audio config.
1256 EXPECT_EQ(
1257 new_bitrate_priority,
1258 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1259 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1260}
1261
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001262// Test that GetRtpReceiveParameters returns the currently configured codecs.
1263TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1264 EXPECT_TRUE(SetupRecvStream());
1265 cricket::AudioRecvParameters parameters;
1266 parameters.codecs.push_back(kIsacCodec);
1267 parameters.codecs.push_back(kPcmuCodec);
1268 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1269
1270 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001271 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001272 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1273 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1274 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1275}
1276
deadbeefcb443432016-12-12 11:12:36 -08001277// Test that GetRtpReceiveParameters returns an SSRC.
1278TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1279 EXPECT_TRUE(SetupRecvStream());
1280 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001281 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001282 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001283 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001284}
1285
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001286// Test that if we set/get parameters multiple times, we get the same results.
1287TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1288 EXPECT_TRUE(SetupRecvStream());
1289 cricket::AudioRecvParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
1292 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1293
1294 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001295 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001296
1297 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001298 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001299
1300 // ... And this shouldn't change the params returned by
1301 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001302 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1303 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001304}
1305
deadbeef3bc15102017-04-20 19:25:07 -07001306// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1307// aren't signaled. It should return an empty "RtpEncodingParameters" when
1308// configured to receive an unsignaled stream and no packets have been received
1309// yet, and start returning the SSRC once a packet has been received.
1310TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1311 ASSERT_TRUE(SetupChannel());
1312 // Call necessary methods to configure receiving a default stream as
1313 // soon as it arrives.
1314 cricket::AudioRecvParameters parameters;
1315 parameters.codecs.push_back(kIsacCodec);
1316 parameters.codecs.push_back(kPcmuCodec);
1317 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1318
1319 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1320 // stream. Should return nothing.
1321 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1322
1323 // Set a sink for an unsignaled stream.
1324 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1325 // Value of "0" means "unsignaled stream".
1326 channel_->SetRawAudioSink(0, std::move(fake_sink));
1327
1328 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1329 // in this method means "unsignaled stream".
1330 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1331 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1332 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1333
1334 // Receive PCMU packet (SSRC=1).
1335 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1336
1337 // The |ssrc| member should still be unset.
1338 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1339 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1340 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1341}
1342
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343// Test that we apply codecs properly.
1344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kIsacCodec);
1348 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001349 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001351 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001353 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1354 EXPECT_EQ(96, send_codec_spec.payload_type);
1355 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1356 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1357 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001358 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001359 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001360}
1361
ossu20a4b3f2017-04-27 02:08:52 -07001362// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1363// AudioSendStream.
1364TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kIsacCodec);
1368 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001369 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 parameters.codecs[0].id = 96;
1371 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001372 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001373 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001374 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001375 // Calling SetSendCodec again with same codec which is already set.
1376 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001377 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001378 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001379}
1380
ossu20a4b3f2017-04-27 02:08:52 -07001381// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1382// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001383
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001384// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].clockrate = 50000;
1391 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392}
1393
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001394// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].bitrate = 0;
1400 parameters.codecs[0].channels = 0;
1401 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402}
1403
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001404// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kOpusCodec);
1409 parameters.codecs[0].bitrate = 0;
1410 parameters.codecs[0].channels = 0;
1411 parameters.codecs[0].params["stereo"] = "1";
1412 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413}
1414
1415// Test that if channel is 1 for opus and there's no stereo, we fail.
1416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 0;
1421 parameters.codecs[0].channels = 1;
1422 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423}
1424
1425// Test that if channel is 1 for opus and stereo=0, we fail.
1426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 0;
1431 parameters.codecs[0].channels = 1;
1432 parameters.codecs[0].params["stereo"] = "0";
1433 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434}
1435
1436// Test that if channel is 1 for opus and stereo=1, we fail.
1437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].bitrate = 0;
1442 parameters.codecs[0].channels = 1;
1443 parameters.codecs[0].params["stereo"] = "1";
1444 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001453 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001454 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455}
1456
ossu20a4b3f2017-04-27 02:08:52 -07001457// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001459 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001460 cricket::AudioSendParameters parameters;
1461 parameters.codecs.push_back(kOpusCodec);
1462 parameters.codecs[0].bitrate = 0;
1463 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001464 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001465 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466}
1467
ossu20a4b3f2017-04-27 02:08:52 -07001468// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001469TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001470 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 cricket::AudioSendParameters parameters;
1472 parameters.codecs.push_back(kOpusCodec);
1473 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001474 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001475 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001478
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001480 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001481 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001482}
1483
ossu20a4b3f2017-04-27 02:08:52 -07001484// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001487 cricket::AudioSendParameters parameters;
1488 parameters.codecs.push_back(kOpusCodec);
1489 parameters.codecs[0].bitrate = 0;
1490 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001491 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001492 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001493}
1494
ossu20a4b3f2017-04-27 02:08:52 -07001495// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001496TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001497 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001498 cricket::AudioSendParameters parameters;
1499 parameters.codecs.push_back(kOpusCodec);
1500 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001501 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001504 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001505
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001506 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001509}
1510
ossu20a4b3f2017-04-27 02:08:52 -07001511// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001513 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001514 cricket::AudioSendParameters parameters;
1515 parameters.codecs.push_back(kOpusCodec);
1516 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001517 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001518 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1519 EXPECT_EQ(111, spec.payload_type);
1520 EXPECT_EQ(96000, spec.target_bitrate_bps);
1521 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001522 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001523 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
ossu20a4b3f2017-04-27 02:08:52 -07001526// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001528 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 cricket::AudioSendParameters parameters;
1530 parameters.codecs.push_back(kOpusCodec);
1531 parameters.codecs[0].bitrate = 30000;
1532 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001544 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001545}
1546
ossu20a4b3f2017-04-27 02:08:52 -07001547// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001550 cricket::AudioSendParameters parameters;
1551 parameters.codecs.push_back(kOpusCodec);
1552 parameters.codecs[0].bitrate = 30000;
1553 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001554 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001555 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001556}
1557
stefan13f1a0a2016-11-30 07:22:58 -08001558TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1559 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1560 200000);
1561}
1562
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1564 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1565}
1566
1567TEST_F(WebRtcVoiceEngineTestFake,
1568 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1569 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1570}
1571
1572TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1573 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1574}
1575
Yves Gerey665174f2018-06-19 15:03:05 +02001576TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001577 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1578 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001579 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001580 // Setting max bitrate should keep previous min bitrate
1581 // Setting max bitrate should not reset start bitrate.
1582 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1583 SetSdpBitrateParameters(
1584 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1585 Field(&BitrateConstraints::start_bitrate_bps, -1),
1586 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001587 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001588}
1589
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001590// Test that we can enable NACK with opus as caller.
1591TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001592 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 cricket::AudioSendParameters parameters;
1594 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001595 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1596 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001598 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001600}
1601
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001602// Test that we can enable NACK with opus as callee.
1603TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001604 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001605 cricket::AudioSendParameters parameters;
1606 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001607 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1608 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001611 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001613
Yves Gerey665174f2018-06-19 15:03:05 +02001614 EXPECT_TRUE(
1615 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001617}
1618
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619// Test that we can enable NACK on receive streams.
1620TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001621 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001623 cricket::AudioSendParameters parameters;
1624 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001625 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1626 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1628 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001630 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1631 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632}
1633
1634// Test that we can disable NACK.
1635TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001636 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001637 cricket::AudioSendParameters parameters;
1638 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001639 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1640 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 parameters.codecs.clear();
1645 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648}
1649
1650// Test that we can disable NACK on receive streams.
1651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001652 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001653 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters parameters;
1655 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001656 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1657 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001659 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1660 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 parameters.codecs.clear();
1663 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001665 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1666 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667}
1668
1669// Test that NACK is enabled on a new receive stream.
1670TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 cricket::AudioSendParameters parameters;
1673 parameters.codecs.push_back(kIsacCodec);
1674 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001675 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1676 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001678 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
solenberg2100c0b2017-03-01 11:29:29 -08001680 EXPECT_TRUE(AddRecvStream(kSsrcY));
1681 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1682 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1683 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684}
1685
stefanba4c0e42016-02-04 04:12:24 -08001686TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001687 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001688 cricket::AudioSendParameters send_parameters;
1689 send_parameters.codecs.push_back(kOpusCodec);
1690 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001692
1693 cricket::AudioRecvParameters recv_parameters;
1694 recv_parameters.codecs.push_back(kIsacCodec);
1695 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001696 EXPECT_TRUE(AddRecvStream(kSsrcX));
1697 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001698 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001699 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001700
ossudedfd282016-06-14 07:12:39 -07001701 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001703 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001704 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001705 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001706}
1707
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001708// Test that we can switch back and forth between Opus and ISAC with CN.
1709TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001711
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001712 cricket::AudioSendParameters opus_parameters;
1713 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001715 {
ossu20a4b3f2017-04-27 02:08:52 -07001716 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1717 EXPECT_EQ(111, spec.payload_type);
1718 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001721 cricket::AudioSendParameters isac_parameters;
1722 isac_parameters.codecs.push_back(kIsacCodec);
1723 isac_parameters.codecs.push_back(kCn16000Codec);
1724 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001726 {
ossu20a4b3f2017-04-27 02:08:52 -07001727 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1728 EXPECT_EQ(103, spec.payload_type);
1729 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001730 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001733 {
ossu20a4b3f2017-04-27 02:08:52 -07001734 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1735 EXPECT_EQ(111, spec.payload_type);
1736 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001737 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001738}
1739
1740// Test that we handle various ways of specifying bitrate.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 cricket::AudioSendParameters parameters;
1744 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001746 {
ossu20a4b3f2017-04-27 02:08:52 -07001747 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1748 EXPECT_EQ(103, spec.payload_type);
1749 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1750 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001751 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752
Yves Gerey665174f2018-06-19 15:03:05 +02001753 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001754 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001755 {
ossu20a4b3f2017-04-27 02:08:52 -07001756 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1757 EXPECT_EQ(103, spec.payload_type);
1758 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1759 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001760 }
Yves Gerey665174f2018-06-19 15:03:05 +02001761 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001763 {
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(103, spec.payload_type);
1766 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1767 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001768 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001769
Yves Gerey665174f2018-06-19 15:03:05 +02001770 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001771 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001772 {
ossu20a4b3f2017-04-27 02:08:52 -07001773 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1774 EXPECT_EQ(0, spec.payload_type);
1775 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1776 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001777 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778
Yves Gerey665174f2018-06-19 15:03:05 +02001779 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001781 {
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(0, spec.payload_type);
1784 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1785 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001786 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001788 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001789 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001790 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001791 {
ossu20a4b3f2017-04-27 02:08:52 -07001792 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1793 EXPECT_EQ(111, spec.payload_type);
1794 EXPECT_STREQ("opus", spec.format.name.c_str());
1795 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001796 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797}
1798
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001799// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001801 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 cricket::AudioSendParameters parameters;
1803 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001804}
1805
1806// Test that we can set send codecs even with telephone-event codec as the first
1807// one on the list.
1808TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001809 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001810 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001811 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 parameters.codecs.push_back(kIsacCodec);
1813 parameters.codecs.push_back(kPcmuCodec);
1814 parameters.codecs[0].id = 98; // DTMF
1815 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001817 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1818 EXPECT_EQ(96, spec.payload_type);
1819 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001820 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001821 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001822}
1823
Harald Alvestranda1f66612018-02-21 11:24:23 +01001824// Test that CanInsertDtmf() is governed by the send flag
1825TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1826 EXPECT_TRUE(SetupSendStream());
1827 cricket::AudioSendParameters parameters;
1828 parameters.codecs.push_back(kTelephoneEventCodec1);
1829 parameters.codecs.push_back(kPcmuCodec);
1830 parameters.codecs[0].id = 98; // DTMF
1831 parameters.codecs[1].id = 96;
1832 SetSendParameters(parameters);
1833 EXPECT_FALSE(channel_->CanInsertDtmf());
1834 SetSend(true);
1835 EXPECT_TRUE(channel_->CanInsertDtmf());
1836 SetSend(false);
1837 EXPECT_FALSE(channel_->CanInsertDtmf());
1838}
1839
solenberg31642aa2016-03-14 08:00:37 -07001840// Test that payload type range is limited for telephone-event codec.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001842 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001843 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001844 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001845 parameters.codecs.push_back(kIsacCodec);
1846 parameters.codecs[0].id = 0; // DTMF
1847 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001848 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001849 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001850 EXPECT_TRUE(channel_->CanInsertDtmf());
1851 parameters.codecs[0].id = 128; // DTMF
1852 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1853 EXPECT_FALSE(channel_->CanInsertDtmf());
1854 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001855 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001856 EXPECT_TRUE(channel_->CanInsertDtmf());
1857 parameters.codecs[0].id = -1; // DTMF
1858 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1859 EXPECT_FALSE(channel_->CanInsertDtmf());
1860}
1861
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001862// Test that we can set send codecs even with CN codec as the first
1863// one on the list.
1864TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001865 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001866 cricket::AudioSendParameters parameters;
1867 parameters.codecs.push_back(kCn16000Codec);
1868 parameters.codecs.push_back(kIsacCodec);
1869 parameters.codecs.push_back(kPcmuCodec);
1870 parameters.codecs[0].id = 98; // wideband CN
1871 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001873 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1874 EXPECT_EQ(96, send_codec_spec.payload_type);
1875 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001876 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
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 caller.
1880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001881 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters parameters;
1883 parameters.codecs.push_back(kIsacCodec);
1884 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001885 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 parameters.codecs.push_back(kCn16000Codec);
1887 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001888 parameters.codecs.push_back(kTelephoneEventCodec1);
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);
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_EQ(96, send_codec_spec.payload_type);
1895 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001896 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001898 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001899 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001900}
1901
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001902// Test that we set VAD and DTMF types correctly as callee.
1903TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001904 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 cricket::AudioSendParameters parameters;
1906 parameters.codecs.push_back(kIsacCodec);
1907 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001908 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 parameters.codecs.push_back(kCn16000Codec);
1910 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001911 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001912 parameters.codecs[0].id = 96;
1913 parameters.codecs[2].id = 97; // wideband CN
1914 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001916 EXPECT_TRUE(
1917 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001918
ossu20a4b3f2017-04-27 02:08:52 -07001919 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1920 EXPECT_EQ(96, send_codec_spec.payload_type);
1921 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001922 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001923 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001924 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001925 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001926}
1927
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928// Test that we only apply VAD if we have a CN codec that matches the
1929// send codec clockrate.
1930TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001931 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001933 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 parameters.codecs.push_back(kIsacCodec);
1935 parameters.codecs.push_back(kCn16000Codec);
1936 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001937 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001938 {
ossu20a4b3f2017-04-27 02:08:52 -07001939 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1940 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001941 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001943 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001945 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001946 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001947 {
ossu20a4b3f2017-04-27 02:08:52 -07001948 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1949 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001950 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001951 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001952 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001954 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001955 {
ossu20a4b3f2017-04-27 02:08:52 -07001956 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1957 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001958 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001959 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001960 }
Brave Yao5225dd82015-03-26 07:39:19 +08001961 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001962 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001963 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001964 {
ossu20a4b3f2017-04-27 02:08:52 -07001965 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1966 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001967 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001968 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969}
1970
1971// Test that we perform case-insensitive matching of codec names.
1972TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001973 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001974 cricket::AudioSendParameters parameters;
1975 parameters.codecs.push_back(kIsacCodec);
1976 parameters.codecs.push_back(kPcmuCodec);
1977 parameters.codecs.push_back(kCn16000Codec);
1978 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001979 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001980 parameters.codecs[0].name = "iSaC";
1981 parameters.codecs[0].id = 96;
1982 parameters.codecs[2].id = 97; // wideband CN
1983 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001985 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1986 EXPECT_EQ(96, send_codec_spec.payload_type);
1987 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001988 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001989 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001990 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001991 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001992}
1993
stefanba4c0e42016-02-04 04:12:24 -08001994class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1995 public:
1996 WebRtcVoiceEngineWithSendSideBweTest()
1997 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1998};
1999
2000TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2001 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002002 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002003 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002004 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2005 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2006 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002007 extension.id);
2008 return;
2009 }
2010 }
2011 FAIL() << "Transport sequence number extension not in header-extension list.";
2012}
2013
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002014// Test support for audio level header extension.
2015TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002016 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002017}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002018TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002019 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002020}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002021
solenbergd4adce42016-11-17 06:26:52 -08002022// Test support for transport sequence number header extension.
2023TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2024 TestSetSendRtpHeaderExtensions(
2025 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002026}
solenbergd4adce42016-11-17 06:26:52 -08002027TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2028 TestSetRecvRtpHeaderExtensions(
2029 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002030}
2031
solenberg1ac56142015-10-13 03:58:19 -07002032// Test that we can create a channel and start sending on it.
2033TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002034 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002035 SetSendParameters(send_parameters_);
2036 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002037 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002038 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002039 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002040}
2041
2042// Test that a channel will send if and only if it has a source and is enabled
2043// for sending.
2044TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002045 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002046 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002047 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002048 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002049 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2050 SetAudioSend(kSsrcX, true, &fake_source_);
2051 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2052 SetAudioSend(kSsrcX, true, nullptr);
2053 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002054}
2055
solenberg94218532016-06-16 10:53:22 -07002056// Test that a channel is muted/unmuted.
2057TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2058 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002059 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002060 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2061 SetAudioSend(kSsrcX, true, nullptr);
2062 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2063 SetAudioSend(kSsrcX, false, nullptr);
2064 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002065}
2066
solenberg6d6e7c52016-04-13 09:07:30 -07002067// Test that SetSendParameters() does not alter a stream's send state.
2068TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2069 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002070 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002071
2072 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002073 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002074 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002075
2076 // Changing RTP header extensions will recreate the AudioSendStream.
2077 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002078 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002079 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002080 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002081
2082 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002083 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002084 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002085
2086 // Changing RTP header extensions will recreate the AudioSendStream.
2087 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002088 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002090}
2091
solenberg1ac56142015-10-13 03:58:19 -07002092// Test that we can create a channel and start playing out on it.
2093TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002094 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002095 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002096 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002097 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002098 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002099 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100}
2101
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102// Test that we can add and remove send streams.
2103TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2104 SetupForMultiSendStream();
2105
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002107 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108
solenbergc96df772015-10-21 13:01:53 -07002109 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002110 EXPECT_TRUE(
2111 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002112 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002114 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 }
tfarina5237aaf2015-11-10 23:44:30 -08002116 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117
solenbergc96df772015-10-21 13:01:53 -07002118 // Delete the send streams.
2119 for (uint32_t ssrc : kSsrcs4) {
2120 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002121 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002122 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123 }
solenbergc96df772015-10-21 13:01:53 -07002124 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125}
2126
2127// Test SetSendCodecs correctly configure the codecs in all send streams.
2128TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2129 SetupForMultiSendStream();
2130
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002132 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002133 EXPECT_TRUE(
2134 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 }
2136
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002137 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002139 parameters.codecs.push_back(kIsacCodec);
2140 parameters.codecs.push_back(kCn16000Codec);
2141 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002142 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143
2144 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002145 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002146 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2147 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002148 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2149 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002150 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002151 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 }
2153
minyue7a973442016-10-20 03:27:12 -07002154 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002155 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002156 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002157 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002158 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2159 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002160 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2161 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002162 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
2164}
2165
2166// Test we can SetSend on all send streams correctly.
2167TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2168 SetupForMultiSendStream();
2169
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002170 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002171 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002172 EXPECT_TRUE(
2173 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002174 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002175 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176 }
2177
2178 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002179 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002180 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002181 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002182 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002183 }
2184
2185 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002186 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002188 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002189 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002190 }
2191}
2192
2193// Test we can set the correct statistics on all send streams.
2194TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2195 SetupForMultiSendStream();
2196
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002198 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002199 EXPECT_TRUE(
2200 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002201 }
solenberg85a04962015-10-27 03:35:21 -07002202
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002203 // Create a receive stream to check that none of the send streams end up in
2204 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002205 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002206
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002208 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002209 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002210 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002211
solenberg85a04962015-10-27 03:35:21 -07002212 // Check stats for the added streams.
2213 {
2214 cricket::VoiceMediaInfo info;
2215 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216
solenberg85a04962015-10-27 03:35:21 -07002217 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002218 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002219 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002220 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002221 }
hbos1acfbd22016-11-17 23:43:29 -08002222 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002223
2224 // We have added one receive stream. We should see empty stats.
2225 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002226 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227 }
solenberg1ac56142015-10-13 03:58:19 -07002228
solenberg2100c0b2017-03-01 11:29:29 -08002229 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002230 {
2231 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002232 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002233 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002234 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002235 EXPECT_EQ(0u, info.receivers.size());
2236 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002237
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002238 // Deliver a new packet - a default receive stream should be created and we
2239 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002240 {
2241 cricket::VoiceMediaInfo info;
2242 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2243 SetAudioReceiveStreamStats();
2244 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002245 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002246 EXPECT_EQ(1u, info.receivers.size());
2247 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002248 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002249 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002250}
2251
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002252// Test that we can add and remove receive streams, and do proper send/playout.
2253// We can receive on multiple streams while sending one stream.
2254TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002255 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002256
solenberg1ac56142015-10-13 03:58:19 -07002257 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002258 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002259 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002260
solenberg1ac56142015-10-13 03:58:19 -07002261 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002263 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002265
solenberg1ac56142015-10-13 03:58:19 -07002266 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002267 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002268
2269 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002270 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2271 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2272 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002273
2274 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002275 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002276 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002277
2278 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002279 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002280 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2281 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002282
aleloi84ef6152016-08-04 05:28:21 -07002283 // Restart playout and make sure recv streams are played out.
2284 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2286 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
aleloi84ef6152016-08-04 05:28:21 -07002288 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2290 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002291}
2292
wu@webrtc.org97077a32013-10-25 21:18:33 +00002293TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002294 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002295 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2296 .Times(1)
2297 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002298 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2299 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002300 send_parameters_.options.tx_agc_target_dbov = 3;
2301 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2302 send_parameters_.options.tx_agc_limiter = true;
2303 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002304 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2305 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2306 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002307 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002308}
2309
minyue6b825df2016-10-31 04:08:32 -07002310TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2311 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002312 send_parameters_.options.audio_network_adaptor = true;
2313 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002314 SetSendParameters(send_parameters_);
2315 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002316 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002317}
2318
2319TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2320 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002321 send_parameters_.options.audio_network_adaptor = true;
2322 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002323 SetSendParameters(send_parameters_);
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 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002327 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002328 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002329 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002330}
2331
2332TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2333 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002334 send_parameters_.options.audio_network_adaptor = true;
2335 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002336 SetSendParameters(send_parameters_);
2337 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002338 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002339 const int initial_num = call_.GetNumCreatedSendStreams();
2340 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002341 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002342 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2343 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002344 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002345 // AudioSendStream not expected to be recreated.
2346 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2347 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002348 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002349}
2350
michaelt6672b262017-01-11 10:17:59 -08002351class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2352 : public WebRtcVoiceEngineTestFake {
2353 public:
2354 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2355 : WebRtcVoiceEngineTestFake(
2356 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2357 "Enabled/") {}
2358};
2359
2360TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2361 EXPECT_TRUE(SetupSendStream());
2362 cricket::AudioSendParameters parameters;
2363 parameters.codecs.push_back(kOpusCodec);
2364 SetSendParameters(parameters);
2365 const int initial_num = call_.GetNumCreatedSendStreams();
2366 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2367
2368 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2369 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002370 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2371 constexpr int kMinOverheadBps =
2372 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002373
2374 constexpr int kOpusMinBitrateBps = 6000;
2375 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002376 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002377 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002378 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002379 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002380
Oskar Sundbom78807582017-11-16 11:09:55 +01002381 parameters.options.audio_network_adaptor = true;
2382 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002383 SetSendParameters(parameters);
2384
ossu11bfc532017-02-16 05:37:06 -08002385 constexpr int kMinOverheadWithAnaBps =
2386 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002387
2388 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002389 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002390
minyuececec102017-03-27 13:04:25 -07002391 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002392 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002393}
2394
minyuececec102017-03-27 13:04:25 -07002395// This test is similar to
2396// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2397// additional field trial.
2398TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2399 SetRtpSendParameterUpdatesMaxBitrate) {
2400 EXPECT_TRUE(SetupSendStream());
2401 cricket::AudioSendParameters send_parameters;
2402 send_parameters.codecs.push_back(kOpusCodec);
2403 SetSendParameters(send_parameters);
2404
2405 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2406 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2407 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2408
2409 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002410 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002411 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002412
2413 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2414#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2415 constexpr int kMinOverhead = 3333;
2416#else
2417 constexpr int kMinOverhead = 6666;
2418#endif
2419 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2420}
2421
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002423// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002425 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002426 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2430 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002431 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002432 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002433 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002434 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002435 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002436 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002437 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438
solenberg85a04962015-10-27 03:35:21 -07002439 // Check stats for the added streams.
2440 {
2441 cricket::VoiceMediaInfo info;
2442 EXPECT_EQ(true, channel_->GetStats(&info));
2443
2444 // We have added one send stream. We should see the stats we've set.
2445 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002446 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002447 // We have added one receive stream. We should see empty stats.
2448 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002449 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002450 }
solenberg1ac56142015-10-13 03:58:19 -07002451
solenberg566ef242015-11-06 15:34:49 -08002452 // Start sending - this affects some reported stats.
2453 {
2454 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002455 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002456 EXPECT_EQ(true, channel_->GetStats(&info));
2457 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002458 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002459 }
2460
solenberg2100c0b2017-03-01 11:29:29 -08002461 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002462 {
2463 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002465 EXPECT_EQ(true, channel_->GetStats(&info));
2466 EXPECT_EQ(1u, info.senders.size());
2467 EXPECT_EQ(0u, info.receivers.size());
2468 }
solenberg1ac56142015-10-13 03:58:19 -07002469
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002470 // Deliver a new packet - a default receive stream should be created and we
2471 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002472 {
2473 cricket::VoiceMediaInfo info;
2474 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2475 SetAudioReceiveStreamStats();
2476 EXPECT_EQ(true, channel_->GetStats(&info));
2477 EXPECT_EQ(1u, info.senders.size());
2478 EXPECT_EQ(1u, info.receivers.size());
2479 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002480 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002481 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482}
2483
2484// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002485// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002488 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2489 EXPECT_TRUE(AddRecvStream(kSsrcY));
2490 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491}
2492
2493// Test that the local SSRC is the same on sending and receiving channels if the
2494// receive channel is created before the send channel.
2495TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002496 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002497 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002498 EXPECT_TRUE(
2499 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002500 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2501 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502}
2503
2504// Test that we can properly receive packets.
2505TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002507 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002508 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002509
Yves Gerey665174f2018-06-19 15:03:05 +02002510 EXPECT_TRUE(
2511 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512}
2513
2514// Test that we can properly receive packets on multiple streams.
2515TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002516 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002517 const uint32_t ssrc1 = 1;
2518 const uint32_t ssrc2 = 2;
2519 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002520 EXPECT_TRUE(AddRecvStream(ssrc1));
2521 EXPECT_TRUE(AddRecvStream(ssrc2));
2522 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002523 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002524 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002525 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002526 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002527 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528 }
mflodman3d7db262016-04-29 00:57:13 -07002529
2530 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2531 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2532 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2533
2534 EXPECT_EQ(s1.received_packets(), 0);
2535 EXPECT_EQ(s2.received_packets(), 0);
2536 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002537
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(s1.received_packets(), 0);
2540 EXPECT_EQ(s2.received_packets(), 0);
2541 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002542
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002544 EXPECT_EQ(s1.received_packets(), 1);
2545 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2546 EXPECT_EQ(s2.received_packets(), 0);
2547 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002548
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002549 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002550 EXPECT_EQ(s1.received_packets(), 1);
2551 EXPECT_EQ(s2.received_packets(), 1);
2552 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2553 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002554
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002556 EXPECT_EQ(s1.received_packets(), 1);
2557 EXPECT_EQ(s2.received_packets(), 1);
2558 EXPECT_EQ(s3.received_packets(), 1);
2559 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002560
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2562 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2563 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564}
2565
solenberg2100c0b2017-03-01 11:29:29 -08002566// Test that receiving on an unsignaled stream works (a stream is created).
2567TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002568 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002569 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002570
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002572
Mirko Bonadeif859e552018-05-30 15:31:29 +02002573 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002574 EXPECT_TRUE(
2575 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002576}
2577
Seth Hampson5897a6e2018-04-03 11:16:33 -07002578// Tests that when we add a stream without SSRCs, but contains a stream_id
2579// that it is stored and its stream id is later used when the first packet
2580// arrives to properly create a receive stream with a sync label.
2581TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2582 const char kSyncLabel[] = "sync_label";
2583 EXPECT_TRUE(SetupChannel());
2584 cricket::StreamParams unsignaled_stream;
2585 unsignaled_stream.set_stream_ids({kSyncLabel});
2586 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2587 // The stream shouldn't have been created at this point because it doesn't
2588 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002589 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002590
2591 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2592
Mirko Bonadeif859e552018-05-30 15:31:29 +02002593 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002594 EXPECT_TRUE(
2595 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2596 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2597
2598 // Removing the unsignaled stream clears the cached parameters. If a new
2599 // default unsignaled receive stream is created it will not have a sync group.
2600 channel_->RemoveRecvStream(0);
2601 channel_->RemoveRecvStream(kSsrc1);
2602
2603 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2604
Mirko Bonadeif859e552018-05-30 15:31:29 +02002605 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002606 EXPECT_TRUE(
2607 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2608 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2609}
2610
solenberg2100c0b2017-03-01 11:29:29 -08002611// Test that receiving N unsignaled stream works (streams will be created), and
2612// that packets are forwarded to them all.
2613TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002614 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002615 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002616 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2617
solenberg2100c0b2017-03-01 11:29:29 -08002618 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002619 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002620 rtc::SetBE32(&packet[8], ssrc);
2621 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002622
solenberg2100c0b2017-03-01 11:29:29 -08002623 // Verify we have one new stream for each loop iteration.
2624 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002625 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2626 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002627 }
mflodman3d7db262016-04-29 00:57:13 -07002628
solenberg2100c0b2017-03-01 11:29:29 -08002629 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002630 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002631 rtc::SetBE32(&packet[8], ssrc);
2632 DeliverPacket(packet, sizeof(packet));
2633
solenbergebb349d2017-03-13 05:46:15 -07002634 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002635 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2636 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2637 }
2638
2639 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2640 constexpr uint32_t kAnotherSsrc = 667;
2641 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002642 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002643
2644 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002645 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002646 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002647 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002648 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2649 EXPECT_EQ(2, streams[i]->received_packets());
2650 }
2651 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2652 EXPECT_EQ(1, streams[i]->received_packets());
2653 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002654 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002655}
2656
solenberg2100c0b2017-03-01 11:29:29 -08002657// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002658// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002659TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002660 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002661 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002662 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2663
2664 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002665 const uint32_t signaled_ssrc = 1;
2666 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002667 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002668 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002669 EXPECT_TRUE(
2670 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002671 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002672
2673 // Note that the first unknown SSRC cannot be 0, because we only support
2674 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002675 const uint32_t unsignaled_ssrc = 7011;
2676 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002677 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002678 EXPECT_TRUE(
2679 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002680 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002681
2682 DeliverPacket(packet, sizeof(packet));
2683 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2684
2685 rtc::SetBE32(&packet[8], signaled_ssrc);
2686 DeliverPacket(packet, sizeof(packet));
2687 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002688 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002689}
2690
solenberg4904fb62017-02-17 12:01:14 -08002691// Two tests to verify that adding a receive stream with the same SSRC as a
2692// previously added unsignaled stream will only recreate underlying stream
2693// objects if the stream parameters have changed.
2694TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2695 EXPECT_TRUE(SetupChannel());
2696
2697 // Spawn unsignaled stream with SSRC=1.
2698 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002699 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002700 EXPECT_TRUE(
2701 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002702
2703 // Verify that the underlying stream object in Call is not recreated when a
2704 // stream with SSRC=1 is added.
2705 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002706 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002707 int audio_receive_stream_id = streams.front()->id();
2708 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002709 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002710 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2711}
2712
2713TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2714 EXPECT_TRUE(SetupChannel());
2715
2716 // Spawn unsignaled stream with SSRC=1.
2717 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002718 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002719 EXPECT_TRUE(
2720 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002721
2722 // Verify that the underlying stream object in Call *is* recreated when a
2723 // stream with SSRC=1 is added, and which has changed stream parameters.
2724 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002725 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002726 int audio_receive_stream_id = streams.front()->id();
2727 cricket::StreamParams stream_params;
2728 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002729 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002730 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002731 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002732 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2733}
2734
solenberg1ac56142015-10-13 03:58:19 -07002735// Test that AddRecvStream creates new stream.
2736TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002737 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002738 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739}
2740
2741// Test that after adding a recv stream, we do not decode more codecs than
2742// those previously passed into SetRecvCodecs.
2743TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002744 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002745 cricket::AudioRecvParameters parameters;
2746 parameters.codecs.push_back(kIsacCodec);
2747 parameters.codecs.push_back(kPcmuCodec);
2748 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002749 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002750 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2751 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2752 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753}
2754
2755// Test that we properly clean up any streams that were added, even if
2756// not explicitly removed.
2757TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002758 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002759 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002760 EXPECT_TRUE(AddRecvStream(1));
2761 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002762
Mirko Bonadeif859e552018-05-30 15:31:29 +02002763 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2764 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765 delete channel_;
2766 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002767 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2768 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769}
2770
wu@webrtc.org78187522013-10-07 23:32:02 +00002771TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002773 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002774}
2775
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002776TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002777 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002778 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002779 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002780}
2781
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002782// Test the InsertDtmf on default send stream as caller.
2783TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002784 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785}
2786
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002787// Test the InsertDtmf on default send stream as callee
2788TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002789 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002790}
2791
2792// Test the InsertDtmf on specified send stream as caller.
2793TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002794 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002795}
2796
2797// Test the InsertDtmf on specified send stream as callee.
2798TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002799 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800}
2801
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002803 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002804 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002805 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2806 .Times(9)
2807 .WillRepeatedly(Return(false));
2808 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2809 .Times(4)
2810 .WillRepeatedly(Return(false));
2811 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2812 .Times(2)
2813 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002814
Mirko Bonadeif859e552018-05-30 15:31:29 +02002815 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002816 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817
solenberg246b8172015-12-08 09:50:23 -08002818 // Nothing set in AudioOptions, so everything should be as default.
2819 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002820 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002821 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002822 EXPECT_TRUE(IsHighPassFilterEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002823 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002824 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825
2826 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002827 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002828 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002829 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830
2831 // Turn echo cancellation back on, with settings, and make sure
2832 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002833 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002834 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002835 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002836
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002837 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2838 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002839 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002840 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002841 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002842
2843 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002844 send_parameters_.options.delay_agnostic_aec = false;
2845 send_parameters_.options.extended_filter_aec = false;
2846 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002847 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002848 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002849
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002850 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002851 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002852 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002853 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002854
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002855 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002856 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002857 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002858 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002859 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002860 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002861
2862 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002863 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002864 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002866 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002867 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002869 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002870 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002871 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002872 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002875 send_parameters_.options.noise_suppression = false;
2876 send_parameters_.options.highpass_filter = false;
2877 send_parameters_.options.typing_detection = false;
2878 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002879 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002880 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002881 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
solenberg1ac56142015-10-13 03:58:19 -07002883 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002884 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002886 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002889 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002890 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891}
2892
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002894 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002895 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2896 .Times(8)
2897 .WillRepeatedly(Return(false));
2898 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2899 .Times(8)
2900 .WillRepeatedly(Return(false));
2901 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2902 .Times(8)
2903 .WillRepeatedly(Return(false));
2904 EXPECT_CALL(adm_, RecordingIsInitialized())
2905 .Times(2)
2906 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002907 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2908 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002909 webrtc::AudioProcessing::Config apm_config;
2910 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002911 .WillRepeatedly(ReturnPointee(&apm_config));
2912 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002913 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002914 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002915
kwiberg686a8ef2016-02-26 03:00:35 -08002916 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002917 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002918 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002919 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002920 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002921 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922
2923 // Have to add a stream to make SetSend work.
2924 cricket::StreamParams stream1;
2925 stream1.ssrcs.push_back(1);
2926 channel1->AddSendStream(stream1);
2927 cricket::StreamParams stream2;
2928 stream2.ssrcs.push_back(2);
2929 channel2->AddSendStream(stream2);
2930
2931 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002933 parameters_options_all.options.echo_cancellation = true;
2934 parameters_options_all.options.auto_gain_control = true;
2935 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002936 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002937 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002938 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002939 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002940 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002941 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002942 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002943 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002944 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002945 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946
2947 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002948 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002949 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002950 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002951 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002952 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002953 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002954 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002955 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002956 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002957 expected_options.echo_cancellation = true;
2958 expected_options.auto_gain_control = true;
2959 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002960 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961
2962 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002963 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002964 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002965 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002966 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002967 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002968 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002969 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002970 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01002971 expected_options.echo_cancellation = true;
2972 expected_options.auto_gain_control = false;
2973 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002974 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975
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(true)).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 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002981 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002982
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002983 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002984 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002985 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002986 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002987 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002988 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002990 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002991 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002992 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002993 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002994 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002995 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002998 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2999 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003000 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3001 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003002 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003003 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003004 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003005 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003006 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003007 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003008 expected_options.echo_cancellation = true;
3009 expected_options.auto_gain_control = false;
3010 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003011 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012}
3013
wu@webrtc.orgde305012013-10-31 15:40:38 +00003014// This test verifies DSCP settings are properly applied on voice media channel.
3015TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003016 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003017 cricket::FakeNetworkInterface network_interface;
3018 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003019 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003020
peahb1c9d1d2017-07-25 15:45:24 -07003021 webrtc::AudioProcessing::Config apm_config;
3022 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003023 .WillRepeatedly(ReturnPointee(&apm_config));
3024 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003025 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003026 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003027
Tim Haloun6ca98362018-09-17 17:06:08 -07003028 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3029 engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
nisse51542be2016-02-12 02:27:06 -08003030 channel->SetInterface(&network_interface);
3031 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3032 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3033
3034 config.enable_dscp = true;
Tim Haloun6ca98362018-09-17 17:06:08 -07003035 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3036 engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
nisse51542be2016-02-12 02:27:06 -08003037 channel->SetInterface(&network_interface);
3038 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3039
Tim Haloun6ca98362018-09-17 17:06:08 -07003040 // Packets should also self-identify their dscp in PacketOptions.
3041 const uint8_t kData[10] = {0};
3042 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
3043 EXPECT_EQ(rtc::DSCP_EF, network_interface.options().dscp);
3044
nisse51542be2016-02-12 02:27:06 -08003045 // Verify that setting the option to false resets the
3046 // DiffServCodePoint.
3047 config.enable_dscp = false;
Tim Haloun6ca98362018-09-17 17:06:08 -07003048 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3049 engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
nisse51542be2016-02-12 02:27:06 -08003050 channel->SetInterface(&network_interface);
3051 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3052 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3053
3054 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003055}
3056
solenberg4bac9c52015-10-09 02:32:53 -07003057TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003058 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003059 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003060 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003061 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003063 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3064 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3065 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003066}
3067
solenberg2100c0b2017-03-01 11:29:29 -08003068TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003069 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003070
3071 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003072 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003073 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3074
3075 // Should remember the volume "2" which will be set on new unsignaled streams,
3076 // and also set the gain to 2 on existing unsignaled streams.
3077 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3078 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3079
3080 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3081 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3082 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3083 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3084 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3085 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3086
3087 // Setting gain with SSRC=0 should affect all unsignaled streams.
3088 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003089 if (kMaxUnsignaledRecvStreams > 1) {
3090 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3091 }
solenberg2100c0b2017-03-01 11:29:29 -08003092 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3093
3094 // Setting gain on an individual stream affects only that.
3095 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003096 if (kMaxUnsignaledRecvStreams > 1) {
3097 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3098 }
solenberg2100c0b2017-03-01 11:29:29 -08003099 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003100}
3101
Seth Hampson845e8782018-03-02 11:34:10 -08003102TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003103 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003104 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003105
solenbergff976312016-03-30 23:28:51 -07003106 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003107 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003108 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003109 // Creating two channels to make sure that sync label is set properly for both
3110 // the default voice channel and following ones.
3111 EXPECT_TRUE(channel_->AddRecvStream(sp));
3112 sp.ssrcs[0] += 1;
3113 EXPECT_TRUE(channel_->AddRecvStream(sp));
3114
Mirko Bonadeif859e552018-05-30 15:31:29 +02003115 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003116 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003117 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003118 << "SyncGroup should be set based on stream id";
3119 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003120 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003121 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003122}
3123
solenberg3a941542015-11-16 07:34:50 -08003124// TODO(solenberg): Remove, once recv streams are configured through Call.
3125// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003126TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 // Test that setting the header extensions results in the expected state
3128 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003129 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 ssrcs.push_back(223);
3131 ssrcs.push_back(224);
3132
solenbergff976312016-03-30 23:28:51 -07003133 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003134 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003135 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003136 EXPECT_TRUE(
3137 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003138 }
3139
Mirko Bonadeif859e552018-05-30 15:31:29 +02003140 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003141 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003142 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003144 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003145 }
3146
3147 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003148 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003149 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003150 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003151 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003152 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003153 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003154 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155 EXPECT_NE(nullptr, s);
3156 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003157 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3158 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003159 for (const auto& s_ext : s_exts) {
3160 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003161 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003162 }
3163 }
3164 }
3165 }
3166
3167 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003168 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003169 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003170 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003171 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003172 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003173 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003174}
3175
3176TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3177 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003178 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003179 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003180 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003181 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3182 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003184 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003185
solenbergff976312016-03-30 23:28:51 -07003186 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003187 cricket::WebRtcVoiceMediaChannel* media_channel =
3188 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003189 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003190 EXPECT_TRUE(media_channel->AddRecvStream(
3191 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3192
Mirko Bonadeif859e552018-05-30 15:31:29 +02003193 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003194 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003195 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003196 EXPECT_EQ(0, s->received_packets());
3197 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3198 EXPECT_EQ(1, s->received_packets());
3199 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3200 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003201}
Minyue2013aec2015-05-13 14:14:42 +02003202
solenberg0a617e22015-10-20 15:49:38 -07003203// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003204// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003205TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003206 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003207 EXPECT_TRUE(AddRecvStream(kSsrcY));
3208 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003209 EXPECT_TRUE(
3210 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3212 EXPECT_TRUE(AddRecvStream(kSsrcW));
3213 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003214}
3215
solenberg7602aab2016-11-14 11:30:07 -08003216TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3217 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003218 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003219 EXPECT_TRUE(
3220 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003221 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3222 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3223 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003224 EXPECT_TRUE(
3225 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003226 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3227 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003228}
stefan658910c2015-09-03 05:48:32 -07003229
deadbeef884f5852016-01-15 09:20:04 -08003230TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003231 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003232 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3233 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003234
3235 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003236 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3237 EXPECT_TRUE(AddRecvStream(kSsrcX));
3238 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003239
3240 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003241 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3242 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003243
3244 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003245 channel_->SetRawAudioSink(kSsrcX, nullptr);
3246 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003247}
3248
solenberg2100c0b2017-03-01 11:29:29 -08003249TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003250 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003251 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3252 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003253 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3254 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003255
3256 // Should be able to set a default sink even when no stream exists.
3257 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3258
solenberg2100c0b2017-03-01 11:29:29 -08003259 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3260 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003261 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003262 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003263
3264 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003265 channel_->SetRawAudioSink(kSsrc0, nullptr);
3266 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003267
3268 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003269 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3270 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003271
3272 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003274 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3276
3277 // Spawn another unsignaled stream - it should be assigned the default sink
3278 // and the previous unsignaled stream should lose it.
3279 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3280 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3281 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3282 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003283 if (kMaxUnsignaledRecvStreams > 1) {
3284 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3285 }
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3287
3288 // Reset the default sink - the second unsignaled stream should lose it.
3289 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003290 if (kMaxUnsignaledRecvStreams > 1) {
3291 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3292 }
solenberg2100c0b2017-03-01 11:29:29 -08003293 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3294
3295 // Try setting the default sink while two streams exists.
3296 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003297 if (kMaxUnsignaledRecvStreams > 1) {
3298 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3299 }
solenberg2100c0b2017-03-01 11:29:29 -08003300 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3301
3302 // Try setting the sink for the first unsignaled stream using its known SSRC.
3303 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003304 if (kMaxUnsignaledRecvStreams > 1) {
3305 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3306 }
solenberg2100c0b2017-03-01 11:29:29 -08003307 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003308 if (kMaxUnsignaledRecvStreams > 1) {
3309 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3310 }
deadbeef884f5852016-01-15 09:20:04 -08003311}
3312
skvlad7a43d252016-03-22 15:32:27 -07003313// Test that, just like the video channel, the voice channel communicates the
3314// network state to the call.
3315TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003316 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003317
3318 EXPECT_EQ(webrtc::kNetworkUp,
3319 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3320 EXPECT_EQ(webrtc::kNetworkUp,
3321 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3322
3323 channel_->OnReadyToSend(false);
3324 EXPECT_EQ(webrtc::kNetworkDown,
3325 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3326 EXPECT_EQ(webrtc::kNetworkUp,
3327 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3328
3329 channel_->OnReadyToSend(true);
3330 EXPECT_EQ(webrtc::kNetworkUp,
3331 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3332 EXPECT_EQ(webrtc::kNetworkUp,
3333 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3334}
3335
aleloi18e0b672016-10-04 02:45:47 -07003336// Test that playout is still started after changing parameters
3337TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3338 SetupRecvStream();
3339 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003340 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003341
3342 // Changing RTP header extensions will recreate the AudioReceiveStream.
3343 cricket::AudioRecvParameters parameters;
3344 parameters.extensions.push_back(
3345 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3346 channel_->SetRecvParameters(parameters);
3347
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003349}
3350
Zhi Huangfa266ef2017-12-13 10:27:46 -08003351// Tests when GetSources is called with non-existing ssrc, it will return an
3352// empty list of RtpSource without crashing.
3353TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3354 // Setup an recv stream with |kSsrcX|.
3355 SetupRecvStream();
3356 cricket::WebRtcVoiceMediaChannel* media_channel =
3357 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3358 // Call GetSources with |kSsrcY| which doesn't exist.
3359 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3360 EXPECT_EQ(0u, sources.size());
3361}
3362
stefan658910c2015-09-03 05:48:32 -07003363// Tests that the library initializes and shuts down properly.
3364TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003365 // If the VoiceEngine wants to gather available codecs early, that's fine but
3366 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003367 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003368 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003369 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003370 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003371 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003372 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003373 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003374 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003375 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003376 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003377 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3378 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003379 EXPECT_TRUE(channel != nullptr);
3380 delete channel;
solenbergff976312016-03-30 23:28:51 -07003381}
stefan658910c2015-09-03 05:48:32 -07003382
solenbergff976312016-03-30 23:28:51 -07003383// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003384TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3385 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003386 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003387 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003388 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003389 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003390 {
peaha9cc40b2017-06-29 08:32:09 -07003391 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003392 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003393 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003394 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003395 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003396 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003397 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003398 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003399 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003400 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3401 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3402 EXPECT_TRUE(channel != nullptr);
3403 delete channel;
3404 }
stefan658910c2015-09-03 05:48:32 -07003405}
3406
ossu20a4b3f2017-04-27 02:08:52 -07003407// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3408TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003409 // TODO(ossu): Why are the payload types of codecs with non-static payload
3410 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003411 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003412 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003413 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003414 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003415 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003416 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003417 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003418 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003419 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3420 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3421 (clockrate == 0 || codec.clockrate == clockrate);
3422 };
3423 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003424 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003425 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003426 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003427 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003428 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003429 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003430 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003431 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003432 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003433 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003434 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003435 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3436 // Remove these checks once both send and receive side assigns payload
3437 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003438 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003439 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003440 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003441 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003442 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003443 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003444 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003445 EXPECT_EQ(111, codec.id);
3446 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3447 EXPECT_EQ("10", codec.params.find("minptime")->second);
3448 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3449 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003450 }
3451 }
stefan658910c2015-09-03 05:48:32 -07003452}
3453
3454// Tests that VoE supports at least 32 channels
3455TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003456 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003457 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003458 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003459 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003460 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003461 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003462 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003463 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003464 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003465 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003466
3467 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003468 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003469 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003470 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3471 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003472 if (!channel)
3473 break;
stefan658910c2015-09-03 05:48:32 -07003474 channels[num_channels++] = channel;
3475 }
3476
Mirko Bonadeif859e552018-05-30 15:31:29 +02003477 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003478 EXPECT_EQ(expected, num_channels);
3479
3480 while (num_channels > 0) {
3481 delete channels[--num_channels];
3482 }
stefan658910c2015-09-03 05:48:32 -07003483}
3484
3485// Test that we set our preferred codecs properly.
3486TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003487 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3488 // - Check that our builtin codecs are usable by Channel.
3489 // - The codecs provided by the engine is usable by Channel.
3490 // It does not check that the codecs in the RecvParameters are actually
3491 // what we sent in - though it's probably reasonable to expect so, if
3492 // SetRecvParameters returns true.
3493 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003494 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003495 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003496 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003497 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003498 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003499 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003500 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003501 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003502 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003503 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003504 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3505 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003506 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003507 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003508 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003509}
ossu9def8002017-02-09 05:14:32 -08003510
3511TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3512 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003513 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3514 {48000, 2, 16000, 10000, 20000}};
3515 spec1.info.allow_comfort_noise = false;
3516 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003517 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003518 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3519 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003520 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003521 specs.push_back(webrtc::AudioCodecSpec{
3522 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3523 {16000, 1, 13300}});
3524 specs.push_back(
3525 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3526 specs.push_back(
3527 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003528
ossueb1fde42017-05-02 06:46:30 -07003529 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3530 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3531 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003532 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003533 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003534 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003535 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003536
peaha9cc40b2017-06-29 08:32:09 -07003537 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003538 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003539 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003540 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003541 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003542 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003543 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003544
3545 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3546 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003547 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3548 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3549 if (codecs.size() > index)
3550 return codecs[index];
3551 return missing_codec;
3552 };
ossu9def8002017-02-09 05:14:32 -08003553
3554 // Ensure the general codecs are generated first and in order.
3555 for (size_t i = 0; i != specs.size(); ++i) {
3556 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3557 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3558 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3559 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3560 }
3561
3562 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003563 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003564 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3565 for (size_t i = 0; i != codecs.size(); ++i) {
3566 const cricket::AudioCodec& codec = codecs[i];
3567 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3568 codec.clockrate == format.clockrate_hz &&
3569 codec.channels == format.num_channels) {
3570 return rtc::checked_cast<int>(i);
3571 }
3572 }
3573 return -1;
3574 };
ossu9def8002017-02-09 05:14:32 -08003575
3576 // Ensure all supplementary codecs are generated last. Their internal ordering
3577 // is not important.
3578 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3579 const int num_specs = static_cast<int>(specs.size());
3580 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3581 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3582 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3583 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3584 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3585 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3586 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3587}