blob: 06bf3fdf2bc35be263837e5d39d315f94cf0ef9a [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
Niels Möller2edab4c2018-10-22 09:48:08 +020014#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "api/rtp_parameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "call/call.h"
19#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "media/base/fake_media_engine.h"
21#include "media/base/fake_network_interface.h"
22#include "media/base/fake_rtp.h"
23#include "media/base/media_constants.h"
24#include "media/engine/fake_webrtc_call.h"
25#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_device/include/mock_audio_device.h"
27#include "modules/audio_processing/include/mock_audio_processing.h"
28#include "pc/channel.h"
29#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010031#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/scoped_ref_ptr.h"
33#include "test/field_trial.h"
34#include "test/gtest.h"
35#include "test/mock_audio_decoder_factory.h"
36#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010040using testing::Field;
solenbergbc37fc82016-04-04 09:54:44 -070041using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070042using testing::ReturnPointee;
43using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070044using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000045
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020046namespace {
Sebastian Jansson8f83b422018-02-21 13:07:13 +010047using webrtc::BitrateConstraints;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020048
solenberg418b7d32017-06-13 00:38:27 -070049constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070050
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
52const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070053const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
55const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070056const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
57const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
Yves Gerey665174f2018-06-19 15:03:05 +020058const cricket::AudioCodec kTelephoneEventCodec1(106,
59 "telephone-event",
60 8000,
61 0,
62 1);
63const cricket::AudioCodec kTelephoneEventCodec2(107,
64 "telephone-event",
65 32000,
66 0,
67 1);
solenberg2779bab2016-11-17 04:45:19 -080068
solenberg2100c0b2017-03-01 11:29:29 -080069const uint32_t kSsrc0 = 0;
70const uint32_t kSsrc1 = 1;
71const uint32_t kSsrcX = 0x99;
72const uint32_t kSsrcY = 0x17;
73const uint32_t kSsrcZ = 0x42;
74const uint32_t kSsrcW = 0x02;
Yves Gerey665174f2018-06-19 15:03:05 +020075const uint32_t kSsrcs4[] = {11, 200, 30, 44};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076
solenberg971cab02016-06-14 10:02:41 -070077constexpr int kRtpHistoryMs = 5000;
78
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010079constexpr webrtc::GainControl::Mode kDefaultAgcMode =
80#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
81 webrtc::GainControl::kFixedDigital;
82#else
83 webrtc::GainControl::kAdaptiveAnalog;
84#endif
85
86constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
87 webrtc::NoiseSuppression::kHigh;
88
solenberg9a5f032222017-03-15 06:14:12 -070089void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
90 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010091
92 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010093 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010094 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010095 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070096#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +020097 EXPECT_CALL(
98 *adm, SetPlayoutDevice(
99 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
100 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
101 .WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700102#else
103 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
104#endif // #if defined(WEBRTC_WIN)
105 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
106 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
107 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100108#if defined(WEBRTC_WIN)
Yves Gerey665174f2018-06-19 15:03:05 +0200109 EXPECT_CALL(
110 *adm, SetRecordingDevice(
111 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
112 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
113 .WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100114#else
115 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
116#endif // #if defined(WEBRTC_WIN)
117 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
118 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
119 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700120 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
122 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100123
124 // Teardown.
125 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
126 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
127 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
128 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Yves Gerey665174f2018-06-19 15:03:05 +0200129 EXPECT_CALL(*adm, Release())
130 .Times(3)
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100131 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700132}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200133} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134
solenbergff976312016-03-30 23:28:51 -0700135// Tests that our stub library "works".
136TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700137 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700138 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700139 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
140 new rtc::RefCountedObject<
141 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700142 webrtc::AudioProcessing::Config apm_config;
143 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
144 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700145 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700146 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700147 {
ossuc54071d2016-08-17 02:45:41 -0700148 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700149 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100150 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700151 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700152 }
solenbergff976312016-03-30 23:28:51 -0700153}
154
deadbeef884f5852016-01-15 09:20:04 -0800155class FakeAudioSink : public webrtc::AudioSinkInterface {
156 public:
157 void OnData(const Data& audio) override {}
158};
159
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800160class FakeAudioSource : public cricket::AudioSource {
161 void SetSink(Sink* sink) override {}
162};
163
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164class WebRtcVoiceEngineTestFake : public testing::Test {
165 public:
stefanba4c0e42016-02-04 04:12:24 -0800166 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
167
168 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700169 : apm_(new rtc::RefCountedObject<
170 StrictMock<webrtc::test::MockAudioProcessing>>()),
171 apm_gc_(*apm_->gain_control()),
peaha9cc40b2017-06-29 08:32:09 -0700172 apm_ns_(*apm_->noise_suppression()),
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));
solenberg76377c52017-02-21 00:54:31 -0800188 // Init does not overwrite default AGC config.
189 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
190 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
191 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800192 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
193 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700194 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800195 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700196 // factories. Those tests should probably be moved elsewhere.
197 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
198 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100199 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100200 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700201 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200202 send_parameters_.codecs.push_back(kPcmuCodec);
203 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100204
solenberg76377c52017-02-21 00:54:31 -0800205 // Default Options.
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200206 EXPECT_TRUE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -0800207 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +0100208 EXPECT_TRUE(IsTypingDetectionEnabled());
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::_));
Sebastian Jansson84848f22018-11-16 10:40:36 +0100213 channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
214 cricket::AudioOptions(),
215 webrtc::CryptoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupRecvStream() {
220 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700221 return false;
222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupSendStream() {
Florent Castellidacec712018-05-24 16:24:21 +0200227 return SetupSendStream(cricket::StreamParams::CreateLegacy(kSsrcX));
228 }
229
230 bool SetupSendStream(const cricket::StreamParams& sp) {
solenbergff976312016-03-30 23:28:51 -0700231 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000232 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
Florent Castellidacec712018-05-24 16:24:21 +0200234 if (!channel_->AddSendStream(sp)) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800235 return false;
236 }
peaha9cc40b2017-06-29 08:32:09 -0700237 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800238 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 }
solenberg8189b022016-06-14 12:13:00 -0700240
241 bool AddRecvStream(uint32_t ssrc) {
242 EXPECT_TRUE(channel_);
243 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
244 }
245
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700247 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700248 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800249 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
250 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700251 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800252 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000253 }
solenberg8189b022016-06-14 12:13:00 -0700254
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700256 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
Niels Möllere6933812018-11-05 13:01:41 +0100257 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 }
solenberg8189b022016-06-14 12:13:00 -0700259
Yves Gerey665174f2018-06-19 15:03:05 +0200260 void TearDown() override { delete channel_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100262 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
263 const auto* send_stream = call_.GetAudioSendStream(ssrc);
264 EXPECT_TRUE(send_stream);
265 return *send_stream;
266 }
267
deadbeef884f5852016-01-15 09:20:04 -0800268 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
269 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
270 EXPECT_TRUE(recv_stream);
271 return *recv_stream;
272 }
273
solenberg3a941542015-11-16 07:34:50 -0800274 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800275 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800276 }
277
solenberg7add0582015-11-20 09:59:34 -0800278 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800279 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800280 }
281
solenberg059fb442016-10-26 05:12:24 -0700282 void SetSend(bool enable) {
283 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700284 if (enable) {
285 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700289 }
solenberg059fb442016-10-26 05:12:24 -0700290 channel_->SetSend(enable);
291 }
292
293 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700294 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700295 ASSERT_TRUE(channel_);
296 EXPECT_TRUE(channel_->SetSendParameters(params));
297 }
298
Yves Gerey665174f2018-06-19 15:03:05 +0200299 void SetAudioSend(uint32_t ssrc,
300 bool enable,
301 cricket::AudioSource* source,
minyue6b825df2016-10-31 04:08:32 -0700302 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700303 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700304 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700305 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700306 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700307 }
308 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700309 }
310
Yves Gerey665174f2018-06-19 15:03:05 +0200311 void TestInsertDtmf(uint32_t ssrc,
312 bool caller,
solenbergffbbcac2016-11-17 05:25:37 -0800313 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700314 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700316 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 // send stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200318 EXPECT_TRUE(
319 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
324 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800327 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330
331 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700332 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
Yves Gerey665174f2018-06-19 15:03:05 +0200334 EXPECT_TRUE(
335 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000336 }
337
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 // Test send.
342 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800343 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800345 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800346 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800347 EXPECT_EQ(codec.id, telephone_event.payload_type);
348 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(2, telephone_event.event_code);
350 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 }
352
Johannes Kron9190b822018-10-29 11:22:05 +0100353 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
354 // For a caller, the answer will be applied in set remote description
355 // where SetSendParameters() is called.
356 EXPECT_TRUE(SetupChannel());
357 EXPECT_TRUE(
358 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
359 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
360 SetSendParameters(send_parameters_);
361 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
362 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
363 }
364
365 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
366 // For a callee, the answer will be applied in set local description
367 // where SetExtmapAllowMixed() and AddSendStream() are called.
368 EXPECT_TRUE(SetupChannel());
369 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
370 EXPECT_TRUE(
371 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
372
373 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
374 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
375 }
376
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 // Test that send bandwidth is set correctly.
378 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000379 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
380 // |expected_result| is the expected result from SetMaxSendBandwidth().
381 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700382 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
383 int max_bitrate,
384 bool expected_result,
385 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200386 cricket::AudioSendParameters parameters;
387 parameters.codecs.push_back(codec);
388 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700389 if (expected_result) {
390 SetSendParameters(parameters);
391 } else {
392 EXPECT_FALSE(channel_->SetSendParameters(parameters));
393 }
solenberg2100c0b2017-03-01 11:29:29 -0800394 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 }
396
skvlade0d46372016-04-07 22:59:22 -0700397 // Sets the per-stream maximum bitrate limit for the specified SSRC.
398 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700399 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700400 EXPECT_EQ(1UL, parameters.encodings.size());
401
Oskar Sundbom78807582017-11-16 11:09:55 +0100402 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800403 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700404 }
405
solenberg059fb442016-10-26 05:12:24 -0700406 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700407 cricket::AudioSendParameters send_parameters;
408 send_parameters.codecs.push_back(codec);
409 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700410 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700411 }
412
ossu20a4b3f2017-04-27 02:08:52 -0700413 void CheckSendCodecBitrate(int32_t ssrc,
414 const char expected_name[],
415 int expected_bitrate) {
416 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
417 EXPECT_EQ(expected_name, spec->format.name);
418 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700419 }
420
Danil Chapovalov00c71832018-06-15 15:58:38 +0200421 absl::optional<int> GetCodecBitrate(int32_t ssrc) {
ossu20a4b3f2017-04-27 02:08:52 -0700422 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700423 }
424
Danil Chapovalov00c71832018-06-15 15:58:38 +0200425 const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
426 int32_t ssrc) {
minyue6b825df2016-10-31 04:08:32 -0700427 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
428 }
429
skvlade0d46372016-04-07 22:59:22 -0700430 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
431 int global_max,
432 int stream_max,
433 bool expected_result,
434 int expected_codec_bitrate) {
435 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800436 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700437
438 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700439 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800440 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700441
442 // Verify that reading back the parameters gives results
443 // consistent with the Set() result.
444 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800445 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700446 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
447 EXPECT_EQ(expected_result ? stream_max : -1,
448 resulting_parameters.encodings[0].max_bitrate_bps);
449
450 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700452 }
453
stefan13f1a0a2016-11-30 07:22:58 -0800454 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
455 int expected_min_bitrate_bps,
456 const char* start_bitrate_kbps,
457 int expected_start_bitrate_bps,
458 const char* max_bitrate_kbps,
459 int expected_max_bitrate_bps) {
460 EXPECT_TRUE(SetupSendStream());
461 auto& codecs = send_parameters_.codecs;
462 codecs.clear();
463 codecs.push_back(kOpusCodec);
464 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
465 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
466 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100467 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
468 SetSdpBitrateParameters(
469 AllOf(Field(&BitrateConstraints::min_bitrate_bps,
470 expected_min_bitrate_bps),
471 Field(&BitrateConstraints::start_bitrate_bps,
472 expected_start_bitrate_bps),
473 Field(&BitrateConstraints::max_bitrate_bps,
474 expected_max_bitrate_bps))));
stefan13f1a0a2016-11-30 07:22:58 -0800475
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100476 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -0800477 }
478
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000479 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700480 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000481
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000484
485 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700486 send_parameters_.extensions.push_back(
487 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700488 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800489 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200492 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700493 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000495
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000496 // Ensure extension is set properly.
497 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700498 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700499 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800500 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
501 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
502 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000503
solenberg7add0582015-11-20 09:59:34 -0800504 // Ensure extension is set properly on new stream.
Yves Gerey665174f2018-06-19 15:03:05 +0200505 EXPECT_TRUE(
506 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -0800507 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
508 call_.GetAudioSendStream(kSsrcY));
509 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
510 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
513 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200514 send_parameters_.codecs.push_back(kPcmuCodec);
515 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700516 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800517 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
518 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000519 }
520
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700522 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000523
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000524 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000526
527 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700528 recv_parameters_.extensions.push_back(
529 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800530 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800531 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000532
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000533 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800534 recv_parameters_.extensions.clear();
535 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800536 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000537
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000538 // Ensure extension is set properly.
539 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700540 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800541 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800542 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
543 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
544 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000545
solenberg7add0582015-11-20 09:59:34 -0800546 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800547 EXPECT_TRUE(AddRecvStream(kSsrcY));
548 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
549 call_.GetAudioReceiveStream(kSsrcY));
550 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
551 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
552 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000553
554 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800555 recv_parameters_.extensions.clear();
556 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800557 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
558 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000559 }
560
solenberg85a04962015-10-27 03:35:21 -0700561 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
562 webrtc::AudioSendStream::Stats stats;
563 stats.local_ssrc = 12;
564 stats.bytes_sent = 345;
565 stats.packets_sent = 678;
566 stats.packets_lost = 9012;
567 stats.fraction_lost = 34.56f;
568 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100569 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700570 stats.ext_seqnum = 789;
571 stats.jitter_ms = 12;
572 stats.rtt_ms = 345;
573 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100574 stats.apm_statistics.delay_median_ms = 234;
575 stats.apm_statistics.delay_standard_deviation_ms = 567;
576 stats.apm_statistics.echo_return_loss = 890;
577 stats.apm_statistics.echo_return_loss_enhancement = 1234;
578 stats.apm_statistics.residual_echo_likelihood = 0.432f;
579 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100580 stats.ana_statistics.bitrate_action_counter = 321;
581 stats.ana_statistics.channel_action_counter = 432;
582 stats.ana_statistics.dtx_action_counter = 543;
583 stats.ana_statistics.fec_action_counter = 654;
584 stats.ana_statistics.frame_length_increase_counter = 765;
585 stats.ana_statistics.frame_length_decrease_counter = 876;
586 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700587 stats.typing_noise_detected = true;
588 return stats;
589 }
590 void SetAudioSendStreamStats() {
591 for (auto* s : call_.GetAudioSendStreams()) {
592 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200593 }
solenberg85a04962015-10-27 03:35:21 -0700594 }
solenberg566ef242015-11-06 15:34:49 -0800595 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
596 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700597 const auto stats = GetAudioSendStreamStats();
598 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
599 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
600 EXPECT_EQ(info.packets_sent, stats.packets_sent);
601 EXPECT_EQ(info.packets_lost, stats.packets_lost);
602 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
603 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800604 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700605 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
606 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
607 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
608 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100609 EXPECT_EQ(info.apm_statistics.delay_median_ms,
610 stats.apm_statistics.delay_median_ms);
611 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
612 stats.apm_statistics.delay_standard_deviation_ms);
613 EXPECT_EQ(info.apm_statistics.echo_return_loss,
614 stats.apm_statistics.echo_return_loss);
615 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
616 stats.apm_statistics.echo_return_loss_enhancement);
617 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
618 stats.apm_statistics.residual_echo_likelihood);
619 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
620 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700621 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
622 stats.ana_statistics.bitrate_action_counter);
623 EXPECT_EQ(info.ana_statistics.channel_action_counter,
624 stats.ana_statistics.channel_action_counter);
625 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
626 stats.ana_statistics.dtx_action_counter);
627 EXPECT_EQ(info.ana_statistics.fec_action_counter,
628 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700629 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
630 stats.ana_statistics.frame_length_increase_counter);
631 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
632 stats.ana_statistics.frame_length_decrease_counter);
633 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
634 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800635 EXPECT_EQ(info.typing_noise_detected,
636 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700637 }
638
639 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
640 webrtc::AudioReceiveStream::Stats stats;
641 stats.remote_ssrc = 123;
642 stats.bytes_rcvd = 456;
643 stats.packets_rcvd = 768;
644 stats.packets_lost = 101;
645 stats.fraction_lost = 23.45f;
646 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100647 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700648 stats.ext_seqnum = 678;
649 stats.jitter_ms = 901;
650 stats.jitter_buffer_ms = 234;
651 stats.jitter_buffer_preferred_ms = 567;
652 stats.delay_estimate_ms = 890;
653 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700654 stats.total_samples_received = 5678901;
655 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200656 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200657 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700658 stats.expand_rate = 5.67f;
659 stats.speech_expand_rate = 8.90f;
660 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200661 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700662 stats.accelerate_rate = 4.56f;
663 stats.preemptive_expand_rate = 7.89f;
664 stats.decoding_calls_to_silence_generator = 12;
665 stats.decoding_calls_to_neteq = 345;
666 stats.decoding_normal = 67890;
667 stats.decoding_plc = 1234;
668 stats.decoding_cng = 5678;
669 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700670 stats.decoding_muted_output = 3456;
671 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200672 return stats;
673 }
674 void SetAudioReceiveStreamStats() {
675 for (auto* s : call_.GetAudioReceiveStreams()) {
676 s->SetStats(GetAudioReceiveStreamStats());
677 }
678 }
679 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700680 const auto stats = GetAudioReceiveStreamStats();
681 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
682 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200683 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
684 stats.packets_rcvd);
685 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
686 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700687 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
688 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800689 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200690 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
691 stats.ext_seqnum);
692 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
694 stats.jitter_buffer_ms);
695 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700696 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200697 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
698 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700699 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700700 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
701 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200702 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200703 EXPECT_EQ(info.jitter_buffer_delay_seconds,
704 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700705 EXPECT_EQ(info.expand_rate, stats.expand_rate);
706 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
707 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200708 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700709 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
710 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200711 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700712 stats.decoding_calls_to_silence_generator);
713 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
714 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
715 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
716 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
717 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700718 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700719 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200720 }
hbos1acfbd22016-11-17 23:43:29 -0800721 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
722 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
723 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
724 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
725 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
726 codec.ToCodecParameters());
727 }
728 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
729 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
730 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
731 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
732 codec.ToCodecParameters());
733 }
734 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200735
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200736 bool IsEchoCancellationEnabled() {
737 return engine_->GetApmConfigForTest().echo_canceller.enabled;
738 }
739
peah8271d042016-11-22 07:24:52 -0800740 bool IsHighPassFilterEnabled() {
741 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
742 }
743
Sam Zackrissonba502232019-01-04 10:36:48 +0100744 bool IsTypingDetectionEnabled() {
745 return engine_->GetApmConfigForTest().voice_detection.enabled;
746 }
747
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000748 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700749 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700750 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800751 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800752 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200753 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700754 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700755 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200756 cricket::AudioSendParameters send_parameters_;
757 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800758 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700759 webrtc::AudioProcessing::Config apm_config_;
760
stefanba4c0e42016-02-04 04:12:24 -0800761 private:
762 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763};
764
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100766TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700767 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768}
769
solenberg31fec402016-05-06 02:13:12 -0700770// Test that we can add a send stream and that it has the correct defaults.
771TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
772 EXPECT_TRUE(SetupChannel());
773 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800774 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
775 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
776 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700777 EXPECT_EQ("", config.rtp.c_name);
778 EXPECT_EQ(0u, config.rtp.extensions.size());
779 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
780 config.send_transport);
781}
782
783// Test that we can add a receive stream and that it has the correct defaults.
784TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
785 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800786 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700787 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800788 GetRecvStreamConfig(kSsrcX);
789 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700790 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
791 EXPECT_FALSE(config.rtp.transport_cc);
792 EXPECT_EQ(0u, config.rtp.extensions.size());
793 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
794 config.rtcp_send_transport);
795 EXPECT_EQ("", config.sync_group);
796}
797
stefanba4c0e42016-02-04 04:12:24 -0800798TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700799 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800800 bool opus_found = false;
801 for (cricket::AudioCodec codec : codecs) {
802 if (codec.name == "opus") {
803 EXPECT_TRUE(HasTransportCc(codec));
804 opus_found = true;
805 }
806 }
807 EXPECT_TRUE(opus_found);
808}
809
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810// Test that we set our inbound codecs properly, including changing PT.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800816 parameters.codecs.push_back(kTelephoneEventCodec1);
817 parameters.codecs.push_back(kTelephoneEventCodec2);
818 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200819 parameters.codecs[2].id = 126;
820 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800821 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700822 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
823 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
824 {{0, {"PCMU", 8000, 1}},
825 {106, {"ISAC", 16000, 1}},
826 {126, {"telephone-event", 8000, 1}},
827 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828}
829
830// Test that we fail to set an unknown inbound codec.
831TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700832 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200833 cricket::AudioRecvParameters parameters;
834 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700835 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200836 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839// Test that we fail if we have duplicate types in the inbound list.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
844 parameters.codecs.push_back(kCn16000Codec);
845 parameters.codecs[1].id = kIsacCodec.id;
846 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
849// Test that we can decode OPUS without stereo parameters.
850TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700851 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 cricket::AudioRecvParameters parameters;
853 parameters.codecs.push_back(kIsacCodec);
854 parameters.codecs.push_back(kPcmuCodec);
855 parameters.codecs.push_back(kOpusCodec);
856 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800857 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700858 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
859 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
860 {{0, {"PCMU", 8000, 1}},
861 {103, {"ISAC", 16000, 1}},
862 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
865// Test that we can decode OPUS with stereo = 0.
866TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700867 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200868 cricket::AudioRecvParameters parameters;
869 parameters.codecs.push_back(kIsacCodec);
870 parameters.codecs.push_back(kPcmuCodec);
871 parameters.codecs.push_back(kOpusCodec);
872 parameters.codecs[2].params["stereo"] = "0";
873 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800874 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700875 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
876 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
877 {{0, {"PCMU", 8000, 1}},
878 {103, {"ISAC", 16000, 1}},
879 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882// Test that we can decode OPUS with stereo = 1.
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
887 parameters.codecs.push_back(kPcmuCodec);
888 parameters.codecs.push_back(kOpusCodec);
889 parameters.codecs[2].params["stereo"] = "1";
890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800891 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700892 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
893 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
894 {{0, {"PCMU", 8000, 1}},
895 {103, {"ISAC", 16000, 1}},
896 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897}
898
899// Test that changes to recv codecs are applied to all streams.
900TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700901 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 cricket::AudioRecvParameters parameters;
903 parameters.codecs.push_back(kIsacCodec);
904 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800905 parameters.codecs.push_back(kTelephoneEventCodec1);
906 parameters.codecs.push_back(kTelephoneEventCodec2);
907 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 parameters.codecs[2].id = 126;
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700910 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
911 EXPECT_TRUE(AddRecvStream(ssrc));
912 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
913 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
914 {{0, {"PCMU", 8000, 1}},
915 {106, {"ISAC", 16000, 1}},
916 {126, {"telephone-event", 8000, 1}},
917 {107, {"telephone-event", 32000, 1}}})));
918 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919}
920
921TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700922 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200923 cricket::AudioRecvParameters parameters;
924 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800925 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200926 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
solenberg2100c0b2017-03-01 11:29:29 -0800928 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200929 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800930 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931}
932
933// Test that we can apply the same set of codecs again while playing.
934TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200936 cricket::AudioRecvParameters parameters;
937 parameters.codecs.push_back(kIsacCodec);
938 parameters.codecs.push_back(kCn16000Codec);
939 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700940 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200941 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942
deadbeefcb383672017-04-26 16:28:42 -0700943 // Remapping a payload type to a different codec should fail.
944 parameters.codecs[0] = kOpusCodec;
945 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200946 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800947 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948}
949
950// Test that we can add a codec while playing.
951TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200953 cricket::AudioRecvParameters parameters;
954 parameters.codecs.push_back(kIsacCodec);
955 parameters.codecs.push_back(kCn16000Codec);
956 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700957 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200959 parameters.codecs.push_back(kOpusCodec);
960 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800961 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962}
963
deadbeefcb383672017-04-26 16:28:42 -0700964// Test that we accept adding the same codec with a different payload type.
965// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
966TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
967 EXPECT_TRUE(SetupRecvStream());
968 cricket::AudioRecvParameters parameters;
969 parameters.codecs.push_back(kIsacCodec);
970 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
971
972 ++parameters.codecs[0].id;
973 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
974}
975
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700977 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000979 // Test that when autobw is enabled, bitrate is kept as the default
980 // value. autobw is enabled for the following tests because the target
981 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
983 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700984 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
986 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700987 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988
ossu20a4b3f2017-04-27 02:08:52 -0700989 // opus, default bitrate == 32000 in mono.
990 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991}
992
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000993TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700994 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700997 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
998 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700999 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001002 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1003 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1004 // Rates above the max (510000) should be capped.
1005 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006}
1007
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001008TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001009 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001010
1011 // Test that we can only set a maximum bitrate for a fixed-rate codec
1012 // if it's bigger than the fixed rate.
1013
1014 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001015 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1016 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1017 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1018 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1019 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1020 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1021 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001022}
1023
1024TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001025 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001026 const int kDesiredBitrate = 128000;
1027 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001028 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001030 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001031
Yves Gerey665174f2018-06-19 15:03:05 +02001032 EXPECT_TRUE(
1033 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001034
solenberg2100c0b2017-03-01 11:29:29 -08001035 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001036}
1037
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038// Test that bitrate cannot be set for CBR codecs.
1039// Bitrate is ignored if it is higher than the fixed bitrate.
1040// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001041TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001042 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043
1044 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001045 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001047
1048 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001049 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001050 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001051
1052 send_parameters_.max_bandwidth_bps = 128;
1053 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001055}
1056
skvlade0d46372016-04-07 22:59:22 -07001057// Test that the per-stream bitrate limit and the global
1058// bitrate limit both apply.
1059TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1060 EXPECT_TRUE(SetupSendStream());
1061
ossu20a4b3f2017-04-27 02:08:52 -07001062 // opus, default bitrate == 32000.
1063 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001064 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1065 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1066 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1067
1068 // CBR codecs allow both maximums to exceed the bitrate.
1069 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1070 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1071 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1072 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1073
1074 // CBR codecs don't allow per stream maximums to be too low.
1075 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1076 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1077}
1078
1079// Test that an attempt to set RtpParameters for a stream that does not exist
1080// fails.
1081TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1082 EXPECT_TRUE(SetupChannel());
1083 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001084 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001085 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001086
1087 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001088 EXPECT_FALSE(
1089 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001090}
1091
1092TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001093 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001094 // This test verifies that setting RtpParameters succeeds only if
1095 // the structure contains exactly one encoding.
1096 // TODO(skvlad): Update this test when we start supporting setting parameters
1097 // for each encoding individually.
1098
1099 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001100 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001101 // Two or more encodings should result in failure.
1102 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001103 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001104 // Zero encodings should also fail.
1105 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001106 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001107}
1108
1109// Changing the SSRC through RtpParameters is not allowed.
1110TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1111 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001112 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001113 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001114 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001115}
1116
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001117// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001118// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001119TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1120 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001121 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001122 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001123 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001124 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001125 ASSERT_EQ(1u, parameters.encodings.size());
1126 ASSERT_TRUE(parameters.encodings[0].active);
1127 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001128 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001129 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001130
1131 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001132 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001133 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001134 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001135 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001136 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001137}
1138
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139// Test that SetRtpSendParameters configures the correct encoding channel for
1140// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001141TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1142 SetupForMultiSendStream();
1143 // Create send streams.
1144 for (uint32_t ssrc : kSsrcs4) {
1145 EXPECT_TRUE(
1146 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1147 }
1148 // Configure one stream to be limited by the stream config, another to be
1149 // limited by the global max, and the third one with no per-stream limit
1150 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001151 SetGlobalMaxBitrate(kOpusCodec, 32000);
1152 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1153 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001154 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1155
ossu20a4b3f2017-04-27 02:08:52 -07001156 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1157 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1158 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001159
1160 // Remove the global cap; the streams should switch to their respective
1161 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001162 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001163 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1164 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1165 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001166}
1167
Tim Haloun648d28a2018-10-18 16:52:22 -07001168// RTCRtpEncodingParameters.network_priority must be one of a few values
1169// derived from the default priority, corresponding to very-low, low, medium,
1170// or high.
1171TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1172 EXPECT_TRUE(SetupSendStream());
1173 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1174 EXPECT_EQ(1UL, parameters.encodings.size());
1175 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1176 parameters.encodings[0].network_priority);
1177
1178 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1179 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1180 for (auto it : good_values) {
1181 parameters.encodings[0].network_priority = it;
1182 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1183 }
1184 for (auto it : bad_values) {
1185 parameters.encodings[0].network_priority = it;
1186 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1187 }
1188}
1189
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001190// Test that GetRtpSendParameters returns the currently configured codecs.
1191TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001192 EXPECT_TRUE(SetupSendStream());
1193 cricket::AudioSendParameters parameters;
1194 parameters.codecs.push_back(kIsacCodec);
1195 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001196 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001197
solenberg2100c0b2017-03-01 11:29:29 -08001198 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001199 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001200 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1201 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001202}
1203
Florent Castellidacec712018-05-24 16:24:21 +02001204// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1205TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1206 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1207 params.cname = "rtcpcname";
1208 EXPECT_TRUE(SetupSendStream(params));
1209
1210 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1211 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1212}
1213
Florent Castelliabe301f2018-06-12 18:33:49 +02001214TEST_F(WebRtcVoiceEngineTestFake,
1215 DetectRtpSendParameterHeaderExtensionsChange) {
1216 EXPECT_TRUE(SetupSendStream());
1217
1218 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1219 rtp_parameters.header_extensions.emplace_back();
1220
1221 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1222
1223 webrtc::RTCError result =
1224 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1225 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1226}
1227
deadbeefcb443432016-12-12 11:12:36 -08001228// Test that GetRtpSendParameters returns an SSRC.
1229TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1230 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001231 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001232 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001233 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001234}
1235
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001236// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001237TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001238 EXPECT_TRUE(SetupSendStream());
1239 cricket::AudioSendParameters parameters;
1240 parameters.codecs.push_back(kIsacCodec);
1241 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001242 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001243
solenberg2100c0b2017-03-01 11:29:29 -08001244 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001245
1246 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001247 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001248
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001249 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001250 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1251 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252}
1253
minyuececec102017-03-27 13:04:25 -07001254// Test that max_bitrate_bps in send stream config gets updated correctly when
1255// SetRtpSendParameters is called.
1256TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1257 webrtc::test::ScopedFieldTrials override_field_trials(
1258 "WebRTC-Audio-SendSideBwe/Enabled/");
1259 EXPECT_TRUE(SetupSendStream());
1260 cricket::AudioSendParameters send_parameters;
1261 send_parameters.codecs.push_back(kOpusCodec);
1262 SetSendParameters(send_parameters);
1263
1264 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1265 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1266 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1267
1268 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001269 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001270 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001271
1272 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1273 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1274}
1275
Seth Hampson24722b32017-12-22 09:36:42 -08001276// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1277// a value <= 0, setting the parameters returns false.
1278TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1279 EXPECT_TRUE(SetupSendStream());
1280 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1281 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1282 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1283 rtp_parameters.encodings[0].bitrate_priority);
1284
1285 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001286 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001287 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001288 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001289}
1290
1291// Test that the bitrate_priority in the send stream config gets updated when
1292// SetRtpSendParameters is set for the VoiceMediaChannel.
1293TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1294 EXPECT_TRUE(SetupSendStream());
1295 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1296
1297 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1298 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1299 rtp_parameters.encodings[0].bitrate_priority);
1300 double new_bitrate_priority = 2.0;
1301 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001302 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001303
1304 // The priority should get set for both the audio channel's rtp parameters
1305 // and the audio send stream's audio config.
1306 EXPECT_EQ(
1307 new_bitrate_priority,
1308 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1309 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1310}
1311
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001312// Test that GetRtpReceiveParameters returns the currently configured codecs.
1313TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1314 EXPECT_TRUE(SetupRecvStream());
1315 cricket::AudioRecvParameters parameters;
1316 parameters.codecs.push_back(kIsacCodec);
1317 parameters.codecs.push_back(kPcmuCodec);
1318 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1319
1320 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001321 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001322 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1323 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1324 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1325}
1326
deadbeefcb443432016-12-12 11:12:36 -08001327// Test that GetRtpReceiveParameters returns an SSRC.
1328TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1329 EXPECT_TRUE(SetupRecvStream());
1330 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001331 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001332 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001333 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001334}
1335
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001336// Test that if we set/get parameters multiple times, we get the same results.
1337TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1338 EXPECT_TRUE(SetupRecvStream());
1339 cricket::AudioRecvParameters parameters;
1340 parameters.codecs.push_back(kIsacCodec);
1341 parameters.codecs.push_back(kPcmuCodec);
1342 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1343
1344 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001345 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001346
1347 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001348 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001349
1350 // ... And this shouldn't change the params returned by
1351 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001352 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1353 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001354}
1355
deadbeef3bc15102017-04-20 19:25:07 -07001356// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1357// aren't signaled. It should return an empty "RtpEncodingParameters" when
1358// configured to receive an unsignaled stream and no packets have been received
1359// yet, and start returning the SSRC once a packet has been received.
1360TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1361 ASSERT_TRUE(SetupChannel());
1362 // Call necessary methods to configure receiving a default stream as
1363 // soon as it arrives.
1364 cricket::AudioRecvParameters parameters;
1365 parameters.codecs.push_back(kIsacCodec);
1366 parameters.codecs.push_back(kPcmuCodec);
1367 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1368
1369 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1370 // stream. Should return nothing.
1371 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1372
1373 // Set a sink for an unsignaled stream.
1374 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1375 // Value of "0" means "unsignaled stream".
1376 channel_->SetRawAudioSink(0, std::move(fake_sink));
1377
1378 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1379 // in this method means "unsignaled stream".
1380 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1381 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1382 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1383
1384 // Receive PCMU packet (SSRC=1).
1385 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1386
1387 // The |ssrc| member should still be unset.
1388 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1389 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1390 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1391}
1392
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393// Test that we apply codecs properly.
1394TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001395 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001396 cricket::AudioSendParameters parameters;
1397 parameters.codecs.push_back(kIsacCodec);
1398 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001399 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001401 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001402 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001403 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1404 EXPECT_EQ(96, send_codec_spec.payload_type);
1405 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1406 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1407 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001408 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001409 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410}
1411
ossu20a4b3f2017-04-27 02:08:52 -07001412// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1413// AudioSendStream.
1414TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001415 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kIsacCodec);
1418 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001419 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].id = 96;
1421 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001422 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001425 // Calling SetSendCodec again with same codec which is already set.
1426 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001427 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001428 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001429}
1430
ossu20a4b3f2017-04-27 02:08:52 -07001431// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1432// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001433
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001434// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 cricket::AudioSendParameters parameters;
1438 parameters.codecs.push_back(kOpusCodec);
1439 parameters.codecs[0].bitrate = 0;
1440 parameters.codecs[0].clockrate = 50000;
1441 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001442}
1443
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001444// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001446 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 cricket::AudioSendParameters parameters;
1448 parameters.codecs.push_back(kOpusCodec);
1449 parameters.codecs[0].bitrate = 0;
1450 parameters.codecs[0].channels = 0;
1451 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001454// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 0;
1460 parameters.codecs[0].channels = 0;
1461 parameters.codecs[0].params["stereo"] = "1";
1462 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
1465// Test that if channel is 1 for opus and there's no stereo, we fail.
1466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 0;
1471 parameters.codecs[0].channels = 1;
1472 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
1475// Test that if channel is 1 for opus and stereo=0, we fail.
1476TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001477 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001478 cricket::AudioSendParameters parameters;
1479 parameters.codecs.push_back(kOpusCodec);
1480 parameters.codecs[0].bitrate = 0;
1481 parameters.codecs[0].channels = 1;
1482 parameters.codecs[0].params["stereo"] = "0";
1483 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484}
1485
1486// Test that if channel is 1 for opus and stereo=1, we fail.
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001488 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001489 cricket::AudioSendParameters parameters;
1490 parameters.codecs.push_back(kOpusCodec);
1491 parameters.codecs[0].bitrate = 0;
1492 parameters.codecs[0].channels = 1;
1493 parameters.codecs[0].params["stereo"] = "1";
1494 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495}
1496
ossu20a4b3f2017-04-27 02:08:52 -07001497// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001499 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001500 cricket::AudioSendParameters parameters;
1501 parameters.codecs.push_back(kOpusCodec);
1502 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001504 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505}
1506
ossu20a4b3f2017-04-27 02:08:52 -07001507// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].bitrate = 0;
1513 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001514 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001515 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516}
1517
ossu20a4b3f2017-04-27 02:08:52 -07001518// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 cricket::AudioSendParameters parameters;
1522 parameters.codecs.push_back(kOpusCodec);
1523 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001524 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001525 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001526 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001527 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001528
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001529 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001531 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001532}
1533
ossu20a4b3f2017-04-27 02:08:52 -07001534// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].bitrate = 0;
1540 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001542 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543}
1544
ossu20a4b3f2017-04-27 02:08:52 -07001545// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001546TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001547 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 cricket::AudioSendParameters parameters;
1549 parameters.codecs.push_back(kOpusCodec);
1550 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001551 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001554 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001555
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001557 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001558 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001559}
1560
ossu20a4b3f2017-04-27 02:08:52 -07001561// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kOpusCodec);
1566 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001567 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001568 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1569 EXPECT_EQ(111, spec.payload_type);
1570 EXPECT_EQ(96000, spec.target_bitrate_bps);
1571 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001572 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001573 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574}
1575
ossu20a4b3f2017-04-27 02:08:52 -07001576// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001578 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001579 cricket::AudioSendParameters parameters;
1580 parameters.codecs.push_back(kOpusCodec);
1581 parameters.codecs[0].bitrate = 30000;
1582 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001584 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585}
1586
ossu20a4b3f2017-04-27 02:08:52 -07001587// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001589 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001590 cricket::AudioSendParameters parameters;
1591 parameters.codecs.push_back(kOpusCodec);
1592 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001593 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001594 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595}
1596
ossu20a4b3f2017-04-27 02:08:52 -07001597// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001599 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kOpusCodec);
1602 parameters.codecs[0].bitrate = 30000;
1603 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001605 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001606}
1607
stefan13f1a0a2016-11-30 07:22:58 -08001608TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1609 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1610 200000);
1611}
1612
1613TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1614 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1615}
1616
1617TEST_F(WebRtcVoiceEngineTestFake,
1618 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1619 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1620}
1621
1622TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1623 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1624}
1625
Yves Gerey665174f2018-06-19 15:03:05 +02001626TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001627 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1628 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001629 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001630 // Setting max bitrate should keep previous min bitrate
1631 // Setting max bitrate should not reset start bitrate.
1632 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1633 SetSdpBitrateParameters(
1634 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1635 Field(&BitrateConstraints::start_bitrate_bps, -1),
1636 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001637 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001638}
1639
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001640// Test that we can enable NACK with opus as callee.
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001642 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001643 cricket::AudioSendParameters parameters;
1644 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001645 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1646 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001649 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001650 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001651
Yves Gerey665174f2018-06-19 15:03:05 +02001652 EXPECT_TRUE(
1653 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001654}
1655
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656// Test that we can enable NACK on receive streams.
1657TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001658 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001659 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001660 cricket::AudioSendParameters parameters;
1661 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001662 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1663 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001664 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001666 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667}
1668
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001669// Test that we can disable NACK on receive streams.
1670TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001672 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001673 cricket::AudioSendParameters parameters;
1674 parameters.codecs.push_back(kOpusCodec);
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, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 parameters.codecs.clear();
1681 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684}
1685
1686// Test that NACK is enabled on a new receive stream.
1687TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kIsacCodec);
1691 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001692 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1693 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001695
solenberg2100c0b2017-03-01 11:29:29 -08001696 EXPECT_TRUE(AddRecvStream(kSsrcY));
1697 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1698 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1699 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700}
1701
stefanba4c0e42016-02-04 04:12:24 -08001702TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001703 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001704 cricket::AudioSendParameters send_parameters;
1705 send_parameters.codecs.push_back(kOpusCodec);
1706 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001708
1709 cricket::AudioRecvParameters recv_parameters;
1710 recv_parameters.codecs.push_back(kIsacCodec);
1711 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001712 EXPECT_TRUE(AddRecvStream(kSsrcX));
1713 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001714 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001715 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001716
ossudedfd282016-06-14 07:12:39 -07001717 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001718 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001719 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001720 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001721 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001722}
1723
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001724// Test that we can switch back and forth between Opus and ISAC with CN.
1725TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001726 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001727
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001728 cricket::AudioSendParameters opus_parameters;
1729 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001730 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001731 {
ossu20a4b3f2017-04-27 02:08:52 -07001732 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1733 EXPECT_EQ(111, spec.payload_type);
1734 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001735 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 cricket::AudioSendParameters isac_parameters;
1738 isac_parameters.codecs.push_back(kIsacCodec);
1739 isac_parameters.codecs.push_back(kCn16000Codec);
1740 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001741 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001742 {
ossu20a4b3f2017-04-27 02:08:52 -07001743 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1744 EXPECT_EQ(103, spec.payload_type);
1745 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001746 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001747
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001749 {
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(111, spec.payload_type);
1752 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001753 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001754}
1755
1756// Test that we handle various ways of specifying bitrate.
1757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001758 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 cricket::AudioSendParameters parameters;
1760 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001761 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001762 {
ossu20a4b3f2017-04-27 02:08:52 -07001763 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1764 EXPECT_EQ(103, spec.payload_type);
1765 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1766 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001767 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768
Yves Gerey665174f2018-06-19 15:03:05 +02001769 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001771 {
ossu20a4b3f2017-04-27 02:08:52 -07001772 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1773 EXPECT_EQ(103, spec.payload_type);
1774 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1775 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001776 }
Yves Gerey665174f2018-06-19 15:03:05 +02001777 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001778 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001779 {
ossu20a4b3f2017-04-27 02:08:52 -07001780 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1781 EXPECT_EQ(103, spec.payload_type);
1782 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1783 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001784 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001785
Yves Gerey665174f2018-06-19 15:03:05 +02001786 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001788 {
ossu20a4b3f2017-04-27 02:08:52 -07001789 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1790 EXPECT_EQ(0, spec.payload_type);
1791 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1792 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001793 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794
Yves Gerey665174f2018-06-19 15:03:05 +02001795 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001796 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001797 {
ossu20a4b3f2017-04-27 02:08:52 -07001798 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1799 EXPECT_EQ(0, spec.payload_type);
1800 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1801 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001802 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001803
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001804 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001805 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001807 {
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(111, spec.payload_type);
1810 EXPECT_STREQ("opus", spec.format.name.c_str());
1811 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001812 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813}
1814
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001815// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001817 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 cricket::AudioSendParameters parameters;
1819 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001820}
1821
1822// Test that we can set send codecs even with telephone-event codec as the first
1823// one on the list.
1824TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001825 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001827 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001828 parameters.codecs.push_back(kIsacCodec);
1829 parameters.codecs.push_back(kPcmuCodec);
1830 parameters.codecs[0].id = 98; // DTMF
1831 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001832 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001833 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1834 EXPECT_EQ(96, spec.payload_type);
1835 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001836 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001837 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001838}
1839
Harald Alvestranda1f66612018-02-21 11:24:23 +01001840// Test that CanInsertDtmf() is governed by the send flag
1841TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1842 EXPECT_TRUE(SetupSendStream());
1843 cricket::AudioSendParameters parameters;
1844 parameters.codecs.push_back(kTelephoneEventCodec1);
1845 parameters.codecs.push_back(kPcmuCodec);
1846 parameters.codecs[0].id = 98; // DTMF
1847 parameters.codecs[1].id = 96;
1848 SetSendParameters(parameters);
1849 EXPECT_FALSE(channel_->CanInsertDtmf());
1850 SetSend(true);
1851 EXPECT_TRUE(channel_->CanInsertDtmf());
1852 SetSend(false);
1853 EXPECT_FALSE(channel_->CanInsertDtmf());
1854}
1855
solenberg31642aa2016-03-14 08:00:37 -07001856// Test that payload type range is limited for telephone-event codec.
1857TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001858 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001859 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001860 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001861 parameters.codecs.push_back(kIsacCodec);
1862 parameters.codecs[0].id = 0; // DTMF
1863 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001865 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001866 EXPECT_TRUE(channel_->CanInsertDtmf());
1867 parameters.codecs[0].id = 128; // DTMF
1868 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1869 EXPECT_FALSE(channel_->CanInsertDtmf());
1870 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001871 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001872 EXPECT_TRUE(channel_->CanInsertDtmf());
1873 parameters.codecs[0].id = -1; // DTMF
1874 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1875 EXPECT_FALSE(channel_->CanInsertDtmf());
1876}
1877
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001878// Test that we can set send codecs even with CN codec as the first
1879// one on the list.
1880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
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(kCn16000Codec);
1884 parameters.codecs.push_back(kIsacCodec);
1885 parameters.codecs.push_back(kPcmuCodec);
1886 parameters.codecs[0].id = 98; // wideband CN
1887 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001888 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001889 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1890 EXPECT_EQ(96, send_codec_spec.payload_type);
1891 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001892 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001893}
1894
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001895// Test that we set VAD and DTMF types correctly as caller.
1896TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001897 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001898 cricket::AudioSendParameters parameters;
1899 parameters.codecs.push_back(kIsacCodec);
1900 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001902 parameters.codecs.push_back(kCn16000Codec);
1903 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001904 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 parameters.codecs[0].id = 96;
1906 parameters.codecs[2].id = 97; // wideband CN
1907 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001908 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001909 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1910 EXPECT_EQ(96, send_codec_spec.payload_type);
1911 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001912 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001913 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001914 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001915 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001916}
1917
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001918// Test that we set VAD and DTMF types correctly as callee.
1919TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001920 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 cricket::AudioSendParameters parameters;
1922 parameters.codecs.push_back(kIsacCodec);
1923 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001924 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001925 parameters.codecs.push_back(kCn16000Codec);
1926 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001927 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 parameters.codecs[0].id = 96;
1929 parameters.codecs[2].id = 97; // wideband CN
1930 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001931 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001932 EXPECT_TRUE(
1933 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001934
ossu20a4b3f2017-04-27 02:08:52 -07001935 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1936 EXPECT_EQ(96, send_codec_spec.payload_type);
1937 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001938 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001939 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001940 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001941 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001942}
1943
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944// Test that we only apply VAD if we have a CN codec that matches the
1945// send codec clockrate.
1946TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001947 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001948 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 parameters.codecs.push_back(kIsacCodec);
1951 parameters.codecs.push_back(kCn16000Codec);
1952 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001953 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001954 {
ossu20a4b3f2017-04-27 02:08:52 -07001955 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1956 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001957 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001958 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001959 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001961 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001962 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001963 {
ossu20a4b3f2017-04-27 02:08:52 -07001964 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1965 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001966 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001967 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001971 {
ossu20a4b3f2017-04-27 02:08:52 -07001972 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1973 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001974 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001975 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001976 }
Brave Yao5225dd82015-03-26 07:39:19 +08001977 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001978 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001979 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001980 {
ossu20a4b3f2017-04-27 02:08:52 -07001981 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1982 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001983 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001984 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001985}
1986
1987// Test that we perform case-insensitive matching of codec names.
1988TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001989 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 cricket::AudioSendParameters parameters;
1991 parameters.codecs.push_back(kIsacCodec);
1992 parameters.codecs.push_back(kPcmuCodec);
1993 parameters.codecs.push_back(kCn16000Codec);
1994 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001995 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001996 parameters.codecs[0].name = "iSaC";
1997 parameters.codecs[0].id = 96;
1998 parameters.codecs[2].id = 97; // wideband CN
1999 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002001 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2002 EXPECT_EQ(96, send_codec_spec.payload_type);
2003 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002004 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002005 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002006 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002007 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002008}
2009
stefanba4c0e42016-02-04 04:12:24 -08002010class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2011 public:
2012 WebRtcVoiceEngineWithSendSideBweTest()
2013 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2014};
2015
2016TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2017 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002018 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002019 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002020 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2021 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2022 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002023 extension.id);
2024 return;
2025 }
2026 }
2027 FAIL() << "Transport sequence number extension not in header-extension list.";
2028}
2029
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002030// Test support for audio level header extension.
2031TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002032 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002033}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002034TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002035 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002036}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002037
solenbergd4adce42016-11-17 06:26:52 -08002038// Test support for transport sequence number header extension.
2039TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2040 TestSetSendRtpHeaderExtensions(
2041 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002042}
solenbergd4adce42016-11-17 06:26:52 -08002043TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2044 TestSetRecvRtpHeaderExtensions(
2045 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002046}
2047
solenberg1ac56142015-10-13 03:58:19 -07002048// Test that we can create a channel and start sending on it.
2049TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002050 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002051 SetSendParameters(send_parameters_);
2052 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002053 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002054 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002055 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002056}
2057
2058// Test that a channel will send if and only if it has a source and is enabled
2059// for sending.
2060TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002061 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002063 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002064 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002065 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2066 SetAudioSend(kSsrcX, true, &fake_source_);
2067 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2068 SetAudioSend(kSsrcX, true, nullptr);
2069 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002070}
2071
solenberg94218532016-06-16 10:53:22 -07002072// Test that a channel is muted/unmuted.
2073TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2074 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002076 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2077 SetAudioSend(kSsrcX, true, nullptr);
2078 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2079 SetAudioSend(kSsrcX, false, nullptr);
2080 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002081}
2082
solenberg6d6e7c52016-04-13 09:07:30 -07002083// Test that SetSendParameters() does not alter a stream's send state.
2084TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2085 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002087
2088 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002089 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002090 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002091
2092 // Changing RTP header extensions will recreate the AudioSendStream.
2093 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002094 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002095 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002096 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002097
2098 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002099 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002100 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002101
2102 // Changing RTP header extensions will recreate the AudioSendStream.
2103 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002104 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002105 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002106}
2107
solenberg1ac56142015-10-13 03:58:19 -07002108// Test that we can create a channel and start playing out on it.
2109TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002110 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002111 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002112 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002113 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002114 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002115 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002116}
2117
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118// Test that we can add and remove send streams.
2119TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2120 SetupForMultiSendStream();
2121
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002123 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124
solenbergc96df772015-10-21 13:01:53 -07002125 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002126 EXPECT_TRUE(
2127 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002128 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002130 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002131 }
tfarina5237aaf2015-11-10 23:44:30 -08002132 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133
solenbergc96df772015-10-21 13:01:53 -07002134 // Delete the send streams.
2135 for (uint32_t ssrc : kSsrcs4) {
2136 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002137 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002138 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 }
solenbergc96df772015-10-21 13:01:53 -07002140 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141}
2142
2143// Test SetSendCodecs correctly configure the codecs in all send streams.
2144TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2145 SetupForMultiSendStream();
2146
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002148 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002149 EXPECT_TRUE(
2150 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002151 }
2152
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002153 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002155 parameters.codecs.push_back(kIsacCodec);
2156 parameters.codecs.push_back(kCn16000Codec);
2157 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002158 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002159
2160 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002161 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002162 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2163 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002164 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2165 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002166 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002167 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002168 }
2169
minyue7a973442016-10-20 03:27:12 -07002170 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002171 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002173 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002174 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2175 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002176 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2177 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002178 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179 }
2180}
2181
2182// Test we can SetSend on all send streams correctly.
2183TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2184 SetupForMultiSendStream();
2185
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002186 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002187 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002188 EXPECT_TRUE(
2189 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002190 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002191 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002192 }
2193
2194 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002195 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002196 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002197 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002198 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002199 }
2200
2201 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002202 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002203 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002204 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002205 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002206 }
2207}
2208
2209// Test we can set the correct statistics on all send streams.
2210TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2211 SetupForMultiSendStream();
2212
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002213 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002214 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002215 EXPECT_TRUE(
2216 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002217 }
solenberg85a04962015-10-27 03:35:21 -07002218
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002219 // Create a receive stream to check that none of the send streams end up in
2220 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002221 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002222
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002223 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002224 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002225 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002226 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002227
solenberg85a04962015-10-27 03:35:21 -07002228 // Check stats for the added streams.
2229 {
2230 cricket::VoiceMediaInfo info;
2231 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002232
solenberg85a04962015-10-27 03:35:21 -07002233 // We have added 4 send streams. We should see empty stats for all.
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 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002236 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002237 }
hbos1acfbd22016-11-17 23:43:29 -08002238 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002239
2240 // We have added one receive stream. We should see empty stats.
2241 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002242 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002243 }
solenberg1ac56142015-10-13 03:58:19 -07002244
solenberg2100c0b2017-03-01 11:29:29 -08002245 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002246 {
2247 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002248 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002249 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002250 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002251 EXPECT_EQ(0u, info.receivers.size());
2252 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002253
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002254 // Deliver a new packet - a default receive stream should be created and we
2255 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002256 {
2257 cricket::VoiceMediaInfo info;
2258 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2259 SetAudioReceiveStreamStats();
2260 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002261 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002262 EXPECT_EQ(1u, info.receivers.size());
2263 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002264 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002265 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002266}
2267
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002268// Test that we can add and remove receive streams, and do proper send/playout.
2269// We can receive on multiple streams while sending one stream.
2270TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002271 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002272
solenberg1ac56142015-10-13 03:58:19 -07002273 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002274 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002275 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002276
solenberg1ac56142015-10-13 03:58:19 -07002277 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002278 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002279 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002280 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002281
solenberg1ac56142015-10-13 03:58:19 -07002282 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002283 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284
2285 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2287 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2288 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002289
2290 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002291 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002292 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002293
2294 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002295 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002296 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2297 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298
aleloi84ef6152016-08-04 05:28:21 -07002299 // Restart playout and make sure recv streams are played out.
2300 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002301 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2302 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002303
aleloi84ef6152016-08-04 05:28:21 -07002304 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002305 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2306 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307}
2308
wu@webrtc.org97077a32013-10-25 21:18:33 +00002309TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002310 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002311 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2312 .Times(1)
2313 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002314 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2315 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002316 send_parameters_.options.tx_agc_target_dbov = 3;
2317 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2318 send_parameters_.options.tx_agc_limiter = true;
2319 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002320 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2321 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2322 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002323 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002324}
2325
minyue6b825df2016-10-31 04:08:32 -07002326TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2327 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002328 send_parameters_.options.audio_network_adaptor = true;
2329 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002330 SetSendParameters(send_parameters_);
2331 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002332 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002333}
2334
2335TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2336 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002337 send_parameters_.options.audio_network_adaptor = true;
2338 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002339 SetSendParameters(send_parameters_);
2340 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002341 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002342 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002343 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002344 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002345 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002346}
2347
2348TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2349 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002350 send_parameters_.options.audio_network_adaptor = true;
2351 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002352 SetSendParameters(send_parameters_);
2353 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002354 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002355 const int initial_num = call_.GetNumCreatedSendStreams();
2356 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002357 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002358 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2359 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002360 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002361 // AudioSendStream not expected to be recreated.
2362 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2363 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002364 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002365}
2366
michaelt6672b262017-01-11 10:17:59 -08002367class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2368 : public WebRtcVoiceEngineTestFake {
2369 public:
2370 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2371 : WebRtcVoiceEngineTestFake(
2372 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2373 "Enabled/") {}
2374};
2375
2376TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2377 EXPECT_TRUE(SetupSendStream());
2378 cricket::AudioSendParameters parameters;
2379 parameters.codecs.push_back(kOpusCodec);
2380 SetSendParameters(parameters);
2381 const int initial_num = call_.GetNumCreatedSendStreams();
2382 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2383
2384 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2385 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002386 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2387 constexpr int kMinOverheadBps =
2388 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002389
2390 constexpr int kOpusMinBitrateBps = 6000;
2391 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002392 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002393 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002394 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002395 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002396
Oskar Sundbom78807582017-11-16 11:09:55 +01002397 parameters.options.audio_network_adaptor = true;
2398 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002399 SetSendParameters(parameters);
2400
ossu11bfc532017-02-16 05:37:06 -08002401 constexpr int kMinOverheadWithAnaBps =
2402 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002403
2404 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002405 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002406
minyuececec102017-03-27 13:04:25 -07002407 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002408 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002409}
2410
minyuececec102017-03-27 13:04:25 -07002411// This test is similar to
2412// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2413// additional field trial.
2414TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2415 SetRtpSendParameterUpdatesMaxBitrate) {
2416 EXPECT_TRUE(SetupSendStream());
2417 cricket::AudioSendParameters send_parameters;
2418 send_parameters.codecs.push_back(kOpusCodec);
2419 SetSendParameters(send_parameters);
2420
2421 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2422 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2423 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2424
2425 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002426 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002427 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002428
2429 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2430#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2431 constexpr int kMinOverhead = 3333;
2432#else
2433 constexpr int kMinOverhead = 6666;
2434#endif
2435 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2436}
2437
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002439// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002441 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002442 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443}
2444
2445TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2446 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002448 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002449 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002450 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002451 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002452 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002453 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454
solenberg85a04962015-10-27 03:35:21 -07002455 // Check stats for the added streams.
2456 {
2457 cricket::VoiceMediaInfo info;
2458 EXPECT_EQ(true, channel_->GetStats(&info));
2459
2460 // We have added one send stream. We should see the stats we've set.
2461 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002462 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002463 // We have added one receive stream. We should see empty stats.
2464 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002465 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002466 }
solenberg1ac56142015-10-13 03:58:19 -07002467
solenberg566ef242015-11-06 15:34:49 -08002468 // Start sending - this affects some reported stats.
2469 {
2470 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002471 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002472 EXPECT_EQ(true, channel_->GetStats(&info));
2473 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002474 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002475 }
2476
solenberg2100c0b2017-03-01 11:29:29 -08002477 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002478 {
2479 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002480 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002481 EXPECT_EQ(true, channel_->GetStats(&info));
2482 EXPECT_EQ(1u, info.senders.size());
2483 EXPECT_EQ(0u, info.receivers.size());
2484 }
solenberg1ac56142015-10-13 03:58:19 -07002485
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002486 // Deliver a new packet - a default receive stream should be created and we
2487 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002488 {
2489 cricket::VoiceMediaInfo info;
2490 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2491 SetAudioReceiveStreamStats();
2492 EXPECT_EQ(true, channel_->GetStats(&info));
2493 EXPECT_EQ(1u, info.senders.size());
2494 EXPECT_EQ(1u, info.receivers.size());
2495 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002496 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002497 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498}
2499
2500// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002501// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002503 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002504 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2505 EXPECT_TRUE(AddRecvStream(kSsrcY));
2506 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507}
2508
2509// Test that the local SSRC is the same on sending and receiving channels if the
2510// receive channel is created before the send channel.
2511TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002512 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002513 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002514 EXPECT_TRUE(
2515 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002516 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2517 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002518}
2519
2520// Test that we can properly receive packets.
2521TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002522 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002523 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002525
Yves Gerey665174f2018-06-19 15:03:05 +02002526 EXPECT_TRUE(
2527 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528}
2529
2530// Test that we can properly receive packets on multiple streams.
2531TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002532 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002533 const uint32_t ssrc1 = 1;
2534 const uint32_t ssrc2 = 2;
2535 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002536 EXPECT_TRUE(AddRecvStream(ssrc1));
2537 EXPECT_TRUE(AddRecvStream(ssrc2));
2538 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002539 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002540 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002541 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002543 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544 }
mflodman3d7db262016-04-29 00:57:13 -07002545
2546 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2547 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2548 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2549
2550 EXPECT_EQ(s1.received_packets(), 0);
2551 EXPECT_EQ(s2.received_packets(), 0);
2552 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002553
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002554 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002555 EXPECT_EQ(s1.received_packets(), 0);
2556 EXPECT_EQ(s2.received_packets(), 0);
2557 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002558
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002559 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002560 EXPECT_EQ(s1.received_packets(), 1);
2561 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2562 EXPECT_EQ(s2.received_packets(), 0);
2563 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002564
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002565 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002566 EXPECT_EQ(s1.received_packets(), 1);
2567 EXPECT_EQ(s2.received_packets(), 1);
2568 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2569 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002570
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002571 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_EQ(s1.received_packets(), 1);
2573 EXPECT_EQ(s2.received_packets(), 1);
2574 EXPECT_EQ(s3.received_packets(), 1);
2575 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002576
mflodman3d7db262016-04-29 00:57:13 -07002577 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2578 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2579 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002580}
2581
solenberg2100c0b2017-03-01 11:29:29 -08002582// Test that receiving on an unsignaled stream works (a stream is created).
2583TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002584 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002585 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002586
solenberg7e63ef02015-11-20 00:19:43 -08002587 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002588
Mirko Bonadeif859e552018-05-30 15:31:29 +02002589 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002590 EXPECT_TRUE(
2591 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002592}
2593
Seth Hampson5897a6e2018-04-03 11:16:33 -07002594// Tests that when we add a stream without SSRCs, but contains a stream_id
2595// that it is stored and its stream id is later used when the first packet
2596// arrives to properly create a receive stream with a sync label.
2597TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2598 const char kSyncLabel[] = "sync_label";
2599 EXPECT_TRUE(SetupChannel());
2600 cricket::StreamParams unsignaled_stream;
2601 unsignaled_stream.set_stream_ids({kSyncLabel});
2602 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2603 // The stream shouldn't have been created at this point because it doesn't
2604 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002605 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002606
2607 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2608
Mirko Bonadeif859e552018-05-30 15:31:29 +02002609 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002610 EXPECT_TRUE(
2611 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2612 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2613
2614 // Removing the unsignaled stream clears the cached parameters. If a new
2615 // default unsignaled receive stream is created it will not have a sync group.
2616 channel_->RemoveRecvStream(0);
2617 channel_->RemoveRecvStream(kSsrc1);
2618
2619 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2620
Mirko Bonadeif859e552018-05-30 15:31:29 +02002621 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002622 EXPECT_TRUE(
2623 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2624 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2625}
2626
solenberg2100c0b2017-03-01 11:29:29 -08002627// Test that receiving N unsignaled stream works (streams will be created), and
2628// that packets are forwarded to them all.
2629TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002630 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002631 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002632 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2633
solenberg2100c0b2017-03-01 11:29:29 -08002634 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002635 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002636 rtc::SetBE32(&packet[8], ssrc);
2637 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002638
solenberg2100c0b2017-03-01 11:29:29 -08002639 // Verify we have one new stream for each loop iteration.
2640 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002641 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2642 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002643 }
mflodman3d7db262016-04-29 00:57:13 -07002644
solenberg2100c0b2017-03-01 11:29:29 -08002645 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002646 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002647 rtc::SetBE32(&packet[8], ssrc);
2648 DeliverPacket(packet, sizeof(packet));
2649
solenbergebb349d2017-03-13 05:46:15 -07002650 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002651 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2652 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2653 }
2654
2655 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2656 constexpr uint32_t kAnotherSsrc = 667;
2657 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002658 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002659
2660 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002661 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002662 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002663 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002664 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2665 EXPECT_EQ(2, streams[i]->received_packets());
2666 }
2667 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2668 EXPECT_EQ(1, streams[i]->received_packets());
2669 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002670 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002671}
2672
solenberg2100c0b2017-03-01 11:29:29 -08002673// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002674// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002675TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002676 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002677 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002678 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2679
2680 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002681 const uint32_t signaled_ssrc = 1;
2682 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002683 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002684 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002685 EXPECT_TRUE(
2686 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002687 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002688
2689 // Note that the first unknown SSRC cannot be 0, because we only support
2690 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002691 const uint32_t unsignaled_ssrc = 7011;
2692 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002693 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002694 EXPECT_TRUE(
2695 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002696 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002697
2698 DeliverPacket(packet, sizeof(packet));
2699 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2700
2701 rtc::SetBE32(&packet[8], signaled_ssrc);
2702 DeliverPacket(packet, sizeof(packet));
2703 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002704 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002705}
2706
solenberg4904fb62017-02-17 12:01:14 -08002707// Two tests to verify that adding a receive stream with the same SSRC as a
2708// previously added unsignaled stream will only recreate underlying stream
2709// objects if the stream parameters have changed.
2710TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2711 EXPECT_TRUE(SetupChannel());
2712
2713 // Spawn unsignaled stream with SSRC=1.
2714 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002715 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002716 EXPECT_TRUE(
2717 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002718
2719 // Verify that the underlying stream object in Call is not recreated when a
2720 // stream with SSRC=1 is added.
2721 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002722 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002723 int audio_receive_stream_id = streams.front()->id();
2724 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002725 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002726 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2727}
2728
2729TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2730 EXPECT_TRUE(SetupChannel());
2731
2732 // Spawn unsignaled stream with SSRC=1.
2733 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002734 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002735 EXPECT_TRUE(
2736 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002737
2738 // Verify that the underlying stream object in Call *is* recreated when a
2739 // stream with SSRC=1 is added, and which has changed stream parameters.
2740 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002741 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002742 int audio_receive_stream_id = streams.front()->id();
2743 cricket::StreamParams stream_params;
2744 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002745 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002746 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002747 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002748 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2749}
2750
solenberg1ac56142015-10-13 03:58:19 -07002751// Test that AddRecvStream creates new stream.
2752TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002753 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002754 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755}
2756
2757// Test that after adding a recv stream, we do not decode more codecs than
2758// those previously passed into SetRecvCodecs.
2759TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002760 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002761 cricket::AudioRecvParameters parameters;
2762 parameters.codecs.push_back(kIsacCodec);
2763 parameters.codecs.push_back(kPcmuCodec);
2764 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002765 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002766 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2767 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2768 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769}
2770
2771// Test that we properly clean up any streams that were added, even if
2772// not explicitly removed.
2773TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002774 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002775 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002776 EXPECT_TRUE(AddRecvStream(1));
2777 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002778
Mirko Bonadeif859e552018-05-30 15:31:29 +02002779 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2780 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781 delete channel_;
2782 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002783 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2784 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785}
2786
wu@webrtc.org78187522013-10-07 23:32:02 +00002787TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002788 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002789 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002790}
2791
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002792TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002793 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002794 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002795 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002796}
2797
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002798// Test the InsertDtmf on default send stream as caller.
2799TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002800 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002803// Test the InsertDtmf on default send stream as callee
2804TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002805 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002806}
2807
2808// Test the InsertDtmf on specified send stream as caller.
2809TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002810 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002811}
2812
2813// Test the InsertDtmf on specified send stream as callee.
2814TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002815 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816}
2817
Johannes Kron9190b822018-10-29 11:22:05 +01002818// Test propagation of extmap allow mixed setting.
2819TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2820 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2821}
2822TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2823 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2824}
2825TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2826 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2827}
2828TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2829 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2830}
2831
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002833 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002834 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002835 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2836 .Times(9)
2837 .WillRepeatedly(Return(false));
2838 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2839 .Times(4)
2840 .WillRepeatedly(Return(false));
2841 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2842 .Times(2)
2843 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002844
Mirko Bonadeif859e552018-05-30 15:31:29 +02002845 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002846 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002847
solenberg246b8172015-12-08 09:50:23 -08002848 // Nothing set in AudioOptions, so everything should be as default.
2849 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002850 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002851 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002852 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002853 EXPECT_TRUE(IsTypingDetectionEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002854 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002855 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856
Sam Zackrissonba502232019-01-04 10:36:48 +01002857 // Turn typing detection off.
2858 send_parameters_.options.typing_detection = false;
2859 SetSendParameters(send_parameters_);
2860 EXPECT_FALSE(IsTypingDetectionEnabled());
2861
2862 // Leave typing detection unchanged, but non-default.
2863 send_parameters_.options.typing_detection = absl::nullopt;
2864 SetSendParameters(send_parameters_);
2865 EXPECT_FALSE(IsTypingDetectionEnabled());
2866
2867 // Turn typing detection on.
2868 send_parameters_.options.typing_detection = true;
2869 SetSendParameters(send_parameters_);
2870 EXPECT_TRUE(IsTypingDetectionEnabled());
2871
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002872 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002873 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002874 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002875 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002876
2877 // Turn echo cancellation back on, with settings, and make sure
2878 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002879 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002880 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002881 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002883 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2884 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002885 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002886 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002887 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002888
2889 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002890 send_parameters_.options.delay_agnostic_aec = false;
2891 send_parameters_.options.extended_filter_aec = false;
2892 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002893 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002894 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002895
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002896 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002897 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002898 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002899 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002900
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002901 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002902 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002903 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002904 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002905 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002906 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907
2908 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002909 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002910 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002911 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002912 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002913 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002915 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002916 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002917 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002920 send_parameters_.options.noise_suppression = false;
2921 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002922 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002923 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002924 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002925 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926
solenberg1ac56142015-10-13 03:58:19 -07002927 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002928 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002930 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002931 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002932 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002933 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002934}
2935
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002937 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002938 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2939 .Times(8)
2940 .WillRepeatedly(Return(false));
2941 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2942 .Times(8)
2943 .WillRepeatedly(Return(false));
2944 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2945 .Times(8)
2946 .WillRepeatedly(Return(false));
2947 EXPECT_CALL(adm_, RecordingIsInitialized())
2948 .Times(2)
2949 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002950 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2951 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002952 webrtc::AudioProcessing::Config apm_config;
2953 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002954 .WillRepeatedly(ReturnPointee(&apm_config));
2955 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002956 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002957 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002958
kwiberg686a8ef2016-02-26 03:00:35 -08002959 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002960 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2961 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2962 cricket::AudioOptions(),
2963 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002964 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002965 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2966 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2967 cricket::AudioOptions(),
2968 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002969
2970 // Have to add a stream to make SetSend work.
2971 cricket::StreamParams stream1;
2972 stream1.ssrcs.push_back(1);
2973 channel1->AddSendStream(stream1);
2974 cricket::StreamParams stream2;
2975 stream2.ssrcs.push_back(2);
2976 channel2->AddSendStream(stream2);
2977
2978 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002979 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002980 parameters_options_all.options.echo_cancellation = true;
2981 parameters_options_all.options.auto_gain_control = true;
2982 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002983 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002984 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002985 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002986 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002987 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002988 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002989 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002990 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002991 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002992 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993
2994 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002995 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002996 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002997 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002998 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002999 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003000 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003001 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003002 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003003 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003004 expected_options.echo_cancellation = true;
3005 expected_options.auto_gain_control = true;
3006 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003007 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008
3009 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003010 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003011 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003012 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003013 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003014 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003015 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003016 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003017 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003018 expected_options.echo_cancellation = true;
3019 expected_options.auto_gain_control = false;
3020 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003021 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003023 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003024 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003025 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003026 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003027 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003028 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003030 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003031 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003032 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003033 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003034 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003035 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003036
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003037 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003038 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003039 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003040 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003041 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003042 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003045 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3046 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003047 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3048 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003049 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003050 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003051 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003052 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003053 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003054 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003055 expected_options.echo_cancellation = true;
3056 expected_options.auto_gain_control = false;
3057 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003058 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003059}
3060
wu@webrtc.orgde305012013-10-31 15:40:38 +00003061// This test verifies DSCP settings are properly applied on voice media channel.
3062TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003063 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003064 cricket::FakeNetworkInterface network_interface;
3065 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003066 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003067 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003068
peahb1c9d1d2017-07-25 15:45:24 -07003069 webrtc::AudioProcessing::Config apm_config;
3070 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003071 .WillRepeatedly(ReturnPointee(&apm_config));
3072 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003073 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003074 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003075
Sebastian Jansson84848f22018-11-16 10:40:36 +01003076 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3077 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3078 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003079 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003080 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3081 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3082
3083 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003084 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3085 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3086 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003087 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003088 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3089
3090 // Create a send stream to configure
3091 EXPECT_TRUE(
3092 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3093 parameters = channel->GetRtpSendParameters(kSsrcZ);
3094 ASSERT_FALSE(parameters.encodings.empty());
3095
3096 // Various priorities map to various dscp values.
3097 parameters.encodings[0].network_priority = 4.0;
3098 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003099 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003100 parameters.encodings[0].network_priority = 0.5;
3101 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3102 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3103
3104 // A bad priority does not change the dscp value.
3105 parameters.encodings[0].network_priority = 0.0;
3106 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3107 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003108
Tim Haloun6ca98362018-09-17 17:06:08 -07003109 // Packets should also self-identify their dscp in PacketOptions.
3110 const uint8_t kData[10] = {0};
3111 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003112 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003113
nisse51542be2016-02-12 02:27:06 -08003114 // Verify that setting the option to false resets the
3115 // DiffServCodePoint.
3116 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003117 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3118 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3119 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003120 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003121 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3122 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3123
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003124 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003125}
3126
solenberg4bac9c52015-10-09 02:32:53 -07003127TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003128 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003129 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003130 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003131 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003132 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003133 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3134 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3135 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003136}
3137
solenberg2100c0b2017-03-01 11:29:29 -08003138TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003139 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003140
3141 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003142 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003143 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3144
3145 // Should remember the volume "2" which will be set on new unsignaled streams,
3146 // and also set the gain to 2 on existing unsignaled streams.
3147 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3148 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3149
3150 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3151 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3152 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3153 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3154 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3155 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3156
3157 // Setting gain with SSRC=0 should affect all unsignaled streams.
3158 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003159 if (kMaxUnsignaledRecvStreams > 1) {
3160 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3161 }
solenberg2100c0b2017-03-01 11:29:29 -08003162 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3163
3164 // Setting gain on an individual stream affects only that.
3165 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003166 if (kMaxUnsignaledRecvStreams > 1) {
3167 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3168 }
solenberg2100c0b2017-03-01 11:29:29 -08003169 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003170}
3171
Seth Hampson845e8782018-03-02 11:34:10 -08003172TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003173 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003174 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003175
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003177 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003178 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003179 // Creating two channels to make sure that sync label is set properly for both
3180 // the default voice channel and following ones.
3181 EXPECT_TRUE(channel_->AddRecvStream(sp));
3182 sp.ssrcs[0] += 1;
3183 EXPECT_TRUE(channel_->AddRecvStream(sp));
3184
Mirko Bonadeif859e552018-05-30 15:31:29 +02003185 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003186 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003187 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003188 << "SyncGroup should be set based on stream id";
3189 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003190 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003191 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003192}
3193
solenberg3a941542015-11-16 07:34:50 -08003194// TODO(solenberg): Remove, once recv streams are configured through Call.
3195// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003196TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003197 // Test that setting the header extensions results in the expected state
3198 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003199 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 ssrcs.push_back(223);
3201 ssrcs.push_back(224);
3202
solenbergff976312016-03-30 23:28:51 -07003203 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003204 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003205 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003206 EXPECT_TRUE(
3207 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003208 }
3209
Mirko Bonadeif859e552018-05-30 15:31:29 +02003210 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003211 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003212 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003213 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003214 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003215 }
3216
3217 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003218 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003219 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003220 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003221 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003222 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003223 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003224 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003225 EXPECT_NE(nullptr, s);
3226 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003227 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3228 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229 for (const auto& s_ext : s_exts) {
3230 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003231 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003232 }
3233 }
3234 }
3235 }
3236
3237 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003238 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003239 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003240 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003241 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003242 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003243 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244}
3245
3246TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3247 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003248 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003249 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003250 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003251 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3252 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003254 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255
solenbergff976312016-03-30 23:28:51 -07003256 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003257 cricket::WebRtcVoiceMediaChannel* media_channel =
3258 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003259 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003260 EXPECT_TRUE(media_channel->AddRecvStream(
3261 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3262
Mirko Bonadeif859e552018-05-30 15:31:29 +02003263 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003264 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003265 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003266 EXPECT_EQ(0, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003267 channel_->OnPacketReceived(&kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003268 EXPECT_EQ(1, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003269 channel_->OnRtcpReceived(&kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003270 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271}
Minyue2013aec2015-05-13 14:14:42 +02003272
solenberg0a617e22015-10-20 15:49:38 -07003273// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003274// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003275TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003276 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_TRUE(AddRecvStream(kSsrcY));
3278 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003279 EXPECT_TRUE(
3280 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3282 EXPECT_TRUE(AddRecvStream(kSsrcW));
3283 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003284}
3285
solenberg7602aab2016-11-14 11:30:07 -08003286TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3287 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003288 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003289 EXPECT_TRUE(
3290 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3292 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3293 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003294 EXPECT_TRUE(
3295 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003296 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3297 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003298}
stefan658910c2015-09-03 05:48:32 -07003299
deadbeef884f5852016-01-15 09:20:04 -08003300TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003301 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003302 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3303 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003304
3305 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003306 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3307 EXPECT_TRUE(AddRecvStream(kSsrcX));
3308 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003309
3310 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003311 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3312 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003313
3314 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003315 channel_->SetRawAudioSink(kSsrcX, nullptr);
3316 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003317}
3318
solenberg2100c0b2017-03-01 11:29:29 -08003319TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003320 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003321 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3322 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003323 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3324 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003325
3326 // Should be able to set a default sink even when no stream exists.
3327 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3328
solenberg2100c0b2017-03-01 11:29:29 -08003329 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3330 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003331 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003332 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003333
3334 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003335 channel_->SetRawAudioSink(kSsrc0, nullptr);
3336 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003337
3338 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003339 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3340 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003341
3342 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003343 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003344 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003345 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3346
3347 // Spawn another unsignaled stream - it should be assigned the default sink
3348 // and the previous unsignaled stream should lose it.
3349 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3350 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3351 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3352 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003353 if (kMaxUnsignaledRecvStreams > 1) {
3354 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3355 }
solenberg2100c0b2017-03-01 11:29:29 -08003356 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3357
3358 // Reset the default sink - the second unsignaled stream should lose it.
3359 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003360 if (kMaxUnsignaledRecvStreams > 1) {
3361 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3362 }
solenberg2100c0b2017-03-01 11:29:29 -08003363 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3364
3365 // Try setting the default sink while two streams exists.
3366 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003367 if (kMaxUnsignaledRecvStreams > 1) {
3368 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3369 }
solenberg2100c0b2017-03-01 11:29:29 -08003370 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3371
3372 // Try setting the sink for the first unsignaled stream using its known SSRC.
3373 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003374 if (kMaxUnsignaledRecvStreams > 1) {
3375 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3376 }
solenberg2100c0b2017-03-01 11:29:29 -08003377 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003378 if (kMaxUnsignaledRecvStreams > 1) {
3379 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3380 }
deadbeef884f5852016-01-15 09:20:04 -08003381}
3382
skvlad7a43d252016-03-22 15:32:27 -07003383// Test that, just like the video channel, the voice channel communicates the
3384// network state to the call.
3385TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003386 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003387
3388 EXPECT_EQ(webrtc::kNetworkUp,
3389 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3390 EXPECT_EQ(webrtc::kNetworkUp,
3391 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3392
3393 channel_->OnReadyToSend(false);
3394 EXPECT_EQ(webrtc::kNetworkDown,
3395 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3396 EXPECT_EQ(webrtc::kNetworkUp,
3397 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3398
3399 channel_->OnReadyToSend(true);
3400 EXPECT_EQ(webrtc::kNetworkUp,
3401 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3402 EXPECT_EQ(webrtc::kNetworkUp,
3403 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3404}
3405
aleloi18e0b672016-10-04 02:45:47 -07003406// Test that playout is still started after changing parameters
3407TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3408 SetupRecvStream();
3409 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003410 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003411
3412 // Changing RTP header extensions will recreate the AudioReceiveStream.
3413 cricket::AudioRecvParameters parameters;
3414 parameters.extensions.push_back(
3415 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3416 channel_->SetRecvParameters(parameters);
3417
solenberg2100c0b2017-03-01 11:29:29 -08003418 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003419}
3420
Zhi Huangfa266ef2017-12-13 10:27:46 -08003421// Tests when GetSources is called with non-existing ssrc, it will return an
3422// empty list of RtpSource without crashing.
3423TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3424 // Setup an recv stream with |kSsrcX|.
3425 SetupRecvStream();
3426 cricket::WebRtcVoiceMediaChannel* media_channel =
3427 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3428 // Call GetSources with |kSsrcY| which doesn't exist.
3429 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3430 EXPECT_EQ(0u, sources.size());
3431}
3432
stefan658910c2015-09-03 05:48:32 -07003433// Tests that the library initializes and shuts down properly.
3434TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003435 // If the VoiceEngine wants to gather available codecs early, that's fine but
3436 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003437 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003438 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003439 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003440 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003441 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003442 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003443 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003444 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003445 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003446 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003447 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3448 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3449 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003450 EXPECT_TRUE(channel != nullptr);
3451 delete channel;
solenbergff976312016-03-30 23:28:51 -07003452}
stefan658910c2015-09-03 05:48:32 -07003453
solenbergff976312016-03-30 23:28:51 -07003454// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003455TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3456 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003457 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003458 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003459 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003460 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003461 {
peaha9cc40b2017-06-29 08:32:09 -07003462 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003463 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003464 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003465 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003466 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003467 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003468 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003469 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003470 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003471 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3472 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3473 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003474 EXPECT_TRUE(channel != nullptr);
3475 delete channel;
3476 }
stefan658910c2015-09-03 05:48:32 -07003477}
3478
ossu20a4b3f2017-04-27 02:08:52 -07003479// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3480TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003481 // TODO(ossu): Why are the payload types of codecs with non-static payload
3482 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003483 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003484 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003485 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003486 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003487 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003488 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003489 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003490 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003491 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003492 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003493 (clockrate == 0 || codec.clockrate == clockrate);
3494 };
3495 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003496 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003497 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003498 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003499 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003500 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003501 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003502 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003503 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003504 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003505 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003506 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003507 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3508 // Remove these checks once both send and receive side assigns payload
3509 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003510 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003511 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003512 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003513 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003514 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003515 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003516 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003517 EXPECT_EQ(111, codec.id);
3518 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3519 EXPECT_EQ("10", codec.params.find("minptime")->second);
3520 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3521 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003522 }
3523 }
stefan658910c2015-09-03 05:48:32 -07003524}
3525
3526// Tests that VoE supports at least 32 channels
3527TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003528 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003529 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003530 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003531 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003532 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003533 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003534 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003535 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003536 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003537 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003538
3539 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003540 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003541 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003542 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3543 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3544 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003545 if (!channel)
3546 break;
stefan658910c2015-09-03 05:48:32 -07003547 channels[num_channels++] = channel;
3548 }
3549
Mirko Bonadeif859e552018-05-30 15:31:29 +02003550 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003551 EXPECT_EQ(expected, num_channels);
3552
3553 while (num_channels > 0) {
3554 delete channels[--num_channels];
3555 }
stefan658910c2015-09-03 05:48:32 -07003556}
3557
3558// Test that we set our preferred codecs properly.
3559TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003560 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3561 // - Check that our builtin codecs are usable by Channel.
3562 // - The codecs provided by the engine is usable by Channel.
3563 // It does not check that the codecs in the RecvParameters are actually
3564 // what we sent in - though it's probably reasonable to expect so, if
3565 // SetRecvParameters returns true.
3566 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003567 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003568 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003569 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003570 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003571 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003572 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003573 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003574 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003575 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003576 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003577 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003578 cricket::AudioOptions(),
3579 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003580 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003581 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003582 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003583}
ossu9def8002017-02-09 05:14:32 -08003584
3585TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3586 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003587 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3588 {48000, 2, 16000, 10000, 20000}};
3589 spec1.info.allow_comfort_noise = false;
3590 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003591 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003592 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3593 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003594 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003595 specs.push_back(webrtc::AudioCodecSpec{
3596 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3597 {16000, 1, 13300}});
3598 specs.push_back(
3599 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3600 specs.push_back(
3601 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003602
ossueb1fde42017-05-02 06:46:30 -07003603 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3604 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3605 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003606 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003607 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003608 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003609 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003610
peaha9cc40b2017-06-29 08:32:09 -07003611 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003612 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003613 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003614 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003615 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003616 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003617 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003618
3619 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3620 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003621 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3622 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3623 if (codecs.size() > index)
3624 return codecs[index];
3625 return missing_codec;
3626 };
ossu9def8002017-02-09 05:14:32 -08003627
3628 // Ensure the general codecs are generated first and in order.
3629 for (size_t i = 0; i != specs.size(); ++i) {
3630 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3631 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3632 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3633 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3634 }
3635
3636 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003637 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003638 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3639 for (size_t i = 0; i != codecs.size(); ++i) {
3640 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003641 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003642 codec.clockrate == format.clockrate_hz &&
3643 codec.channels == format.num_channels) {
3644 return rtc::checked_cast<int>(i);
3645 }
3646 }
3647 return -1;
3648 };
ossu9def8002017-02-09 05:14:32 -08003649
3650 // Ensure all supplementary codecs are generated last. Their internal ordering
3651 // is not important.
3652 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3653 const int num_specs = static_cast<int>(specs.size());
3654 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3655 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3656 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3657 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3658 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3659 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3660 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3661}