blob: 663dd8caba0584c354a9f5ed36fbb0df0df6e07f [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 Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "call/call.h"
20#include "logging/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/base/fake_media_engine.h"
22#include "media/base/fake_network_interface.h"
23#include "media/base/fake_rtp.h"
24#include "media/base/media_constants.h"
25#include "media/engine/fake_webrtc_call.h"
26#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_device/include/mock_audio_device.h"
28#include "modules/audio_processing/include/mock_audio_processing.h"
29#include "pc/channel.h"
30#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/byte_order.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010032#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#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;
Chen Xing0acffb52019-01-15 15:46:29 +0100658 stats.jitter_buffer_emitted_count = 77;
solenberg85a04962015-10-27 03:35:21 -0700659 stats.expand_rate = 5.67f;
660 stats.speech_expand_rate = 8.90f;
661 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200662 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700663 stats.accelerate_rate = 4.56f;
664 stats.preemptive_expand_rate = 7.89f;
665 stats.decoding_calls_to_silence_generator = 12;
666 stats.decoding_calls_to_neteq = 345;
667 stats.decoding_normal = 67890;
668 stats.decoding_plc = 1234;
669 stats.decoding_cng = 5678;
670 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700671 stats.decoding_muted_output = 3456;
672 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200673 return stats;
674 }
675 void SetAudioReceiveStreamStats() {
676 for (auto* s : call_.GetAudioReceiveStreams()) {
677 s->SetStats(GetAudioReceiveStreamStats());
678 }
679 }
680 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700681 const auto stats = GetAudioReceiveStreamStats();
682 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
683 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200684 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_rcvd),
685 stats.packets_rcvd);
686 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.packets_lost),
687 stats.packets_lost);
solenberg85a04962015-10-27 03:35:21 -0700688 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
689 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800690 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200691 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.ext_seqnum),
692 stats.ext_seqnum);
693 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_ms), stats.jitter_ms);
694 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_ms),
695 stats.jitter_buffer_ms);
696 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.jitter_buffer_preferred_ms),
solenberg85a04962015-10-27 03:35:21 -0700697 stats.jitter_buffer_preferred_ms);
Mirko Bonadeif859e552018-05-30 15:31:29 +0200698 EXPECT_EQ(rtc::checked_cast<unsigned int>(info.delay_estimate_ms),
699 stats.delay_estimate_ms);
solenberg85a04962015-10-27 03:35:21 -0700700 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700701 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
702 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200703 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200704 EXPECT_EQ(info.jitter_buffer_delay_seconds,
705 stats.jitter_buffer_delay_seconds);
Chen Xing0acffb52019-01-15 15:46:29 +0100706 EXPECT_EQ(info.jitter_buffer_emitted_count,
707 stats.jitter_buffer_emitted_count);
solenberg85a04962015-10-27 03:35:21 -0700708 EXPECT_EQ(info.expand_rate, stats.expand_rate);
709 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
710 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200711 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700712 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
713 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200714 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700715 stats.decoding_calls_to_silence_generator);
716 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
717 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
718 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
719 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
720 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700721 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700722 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200723 }
hbos1acfbd22016-11-17 23:43:29 -0800724 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
725 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
726 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
727 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
728 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
729 codec.ToCodecParameters());
730 }
731 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
732 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
733 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
734 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
735 codec.ToCodecParameters());
736 }
737 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200738
Sam Zackrisson7988e5c2018-09-24 17:35:22 +0200739 bool IsEchoCancellationEnabled() {
740 return engine_->GetApmConfigForTest().echo_canceller.enabled;
741 }
742
peah8271d042016-11-22 07:24:52 -0800743 bool IsHighPassFilterEnabled() {
744 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
745 }
746
Sam Zackrissonba502232019-01-04 10:36:48 +0100747 bool IsTypingDetectionEnabled() {
748 return engine_->GetApmConfigForTest().voice_detection.enabled;
749 }
750
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700752 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700753 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800754 webrtc::test::MockGainControl& apm_gc_;
solenberg76377c52017-02-21 00:54:31 -0800755 webrtc::test::MockNoiseSuppression& apm_ns_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200756 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700757 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700758 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200759 cricket::AudioSendParameters send_parameters_;
760 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800761 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700762 webrtc::AudioProcessing::Config apm_config_;
763
stefanba4c0e42016-02-04 04:12:24 -0800764 private:
765 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766};
767
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768// Tests that we can create and destroy a channel.
Sebastian Jansson84848f22018-11-16 10:40:36 +0100769TEST_F(WebRtcVoiceEngineTestFake, CreateMediaChannel) {
solenbergff976312016-03-30 23:28:51 -0700770 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771}
772
solenberg31fec402016-05-06 02:13:12 -0700773// Test that we can add a send stream and that it has the correct defaults.
774TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
775 EXPECT_TRUE(SetupChannel());
776 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800777 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
778 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
779 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700780 EXPECT_EQ("", config.rtp.c_name);
781 EXPECT_EQ(0u, config.rtp.extensions.size());
782 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
783 config.send_transport);
784}
785
786// Test that we can add a receive stream and that it has the correct defaults.
787TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
788 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800789 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700790 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800791 GetRecvStreamConfig(kSsrcX);
792 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700793 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
794 EXPECT_FALSE(config.rtp.transport_cc);
795 EXPECT_EQ(0u, config.rtp.extensions.size());
796 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
797 config.rtcp_send_transport);
798 EXPECT_EQ("", config.sync_group);
799}
800
stefanba4c0e42016-02-04 04:12:24 -0800801TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700802 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800803 bool opus_found = false;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100804 for (const cricket::AudioCodec& codec : codecs) {
stefanba4c0e42016-02-04 04:12:24 -0800805 if (codec.name == "opus") {
806 EXPECT_TRUE(HasTransportCc(codec));
807 opus_found = true;
808 }
809 }
810 EXPECT_TRUE(opus_found);
811}
812
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813// Test that we set our inbound codecs properly, including changing PT.
814TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700815 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200816 cricket::AudioRecvParameters parameters;
817 parameters.codecs.push_back(kIsacCodec);
818 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800819 parameters.codecs.push_back(kTelephoneEventCodec1);
820 parameters.codecs.push_back(kTelephoneEventCodec2);
821 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200822 parameters.codecs[2].id = 126;
823 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800824 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700825 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
826 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
827 {{0, {"PCMU", 8000, 1}},
828 {106, {"ISAC", 16000, 1}},
829 {126, {"telephone-event", 8000, 1}},
830 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831}
832
833// Test that we fail to set an unknown inbound codec.
834TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700835 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200836 cricket::AudioRecvParameters parameters;
837 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700838 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200839 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840}
841
842// Test that we fail if we have duplicate types in the inbound list.
843TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700844 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 cricket::AudioRecvParameters parameters;
846 parameters.codecs.push_back(kIsacCodec);
847 parameters.codecs.push_back(kCn16000Codec);
848 parameters.codecs[1].id = kIsacCodec.id;
849 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850}
851
852// Test that we can decode OPUS without stereo parameters.
853TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700854 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 cricket::AudioRecvParameters parameters;
856 parameters.codecs.push_back(kIsacCodec);
857 parameters.codecs.push_back(kPcmuCodec);
858 parameters.codecs.push_back(kOpusCodec);
859 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800860 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700861 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
862 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
863 {{0, {"PCMU", 8000, 1}},
864 {103, {"ISAC", 16000, 1}},
865 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866}
867
868// Test that we can decode OPUS with stereo = 0.
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 cricket::AudioRecvParameters parameters;
872 parameters.codecs.push_back(kIsacCodec);
873 parameters.codecs.push_back(kPcmuCodec);
874 parameters.codecs.push_back(kOpusCodec);
875 parameters.codecs[2].params["stereo"] = "0";
876 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800877 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700878 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
879 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
880 {{0, {"PCMU", 8000, 1}},
881 {103, {"ISAC", 16000, 1}},
882 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883}
884
885// Test that we can decode OPUS with stereo = 1.
886TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700887 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200888 cricket::AudioRecvParameters parameters;
889 parameters.codecs.push_back(kIsacCodec);
890 parameters.codecs.push_back(kPcmuCodec);
891 parameters.codecs.push_back(kOpusCodec);
892 parameters.codecs[2].params["stereo"] = "1";
893 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800894 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700895 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
896 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
897 {{0, {"PCMU", 8000, 1}},
898 {103, {"ISAC", 16000, 1}},
899 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900}
901
902// Test that changes to recv codecs are applied to all streams.
903TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700904 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200905 cricket::AudioRecvParameters parameters;
906 parameters.codecs.push_back(kIsacCodec);
907 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800908 parameters.codecs.push_back(kTelephoneEventCodec1);
909 parameters.codecs.push_back(kTelephoneEventCodec2);
910 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 parameters.codecs[2].id = 126;
912 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700913 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
914 EXPECT_TRUE(AddRecvStream(ssrc));
915 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
916 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
917 {{0, {"PCMU", 8000, 1}},
918 {106, {"ISAC", 16000, 1}},
919 {126, {"telephone-event", 8000, 1}},
920 {107, {"telephone-event", 32000, 1}}})));
921 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922}
923
924TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700925 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800928 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
solenberg2100c0b2017-03-01 11:29:29 -0800931 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
Mirko Bonadeif859e552018-05-30 15:31:29 +0200932 ASSERT_EQ(1u, dm.count(106));
kwibergd32bf752017-01-19 07:03:59 -0800933 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934}
935
936// Test that we can apply the same set of codecs again while playing.
937TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200939 cricket::AudioRecvParameters parameters;
940 parameters.codecs.push_back(kIsacCodec);
941 parameters.codecs.push_back(kCn16000Codec);
942 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700943 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200944 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
deadbeefcb383672017-04-26 16:28:42 -0700946 // Remapping a payload type to a different codec should fail.
947 parameters.codecs[0] = kOpusCodec;
948 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200949 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800950 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951}
952
953// Test that we can add a codec while playing.
954TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200956 cricket::AudioRecvParameters parameters;
957 parameters.codecs.push_back(kIsacCodec);
958 parameters.codecs.push_back(kCn16000Codec);
959 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700960 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 parameters.codecs.push_back(kOpusCodec);
963 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800964 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965}
966
deadbeefcb383672017-04-26 16:28:42 -0700967// Test that we accept adding the same codec with a different payload type.
968// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
969TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
970 EXPECT_TRUE(SetupRecvStream());
971 cricket::AudioRecvParameters parameters;
972 parameters.codecs.push_back(kIsacCodec);
973 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
974
975 ++parameters.codecs[0].id;
976 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
977}
978
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700980 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000982 // Test that when autobw is enabled, bitrate is kept as the default
983 // value. autobw is enabled for the following tests because the target
984 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
986 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700987 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988
989 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700990 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991
ossu20a4b3f2017-04-27 02:08:52 -0700992 // opus, default bitrate == 32000 in mono.
993 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994}
995
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000996TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700997 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -07001000 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
1001 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -07001002 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001005 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
1006 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
1007 // Rates above the max (510000) should be capped.
1008 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001009}
1010
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001011TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001012 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001013
1014 // Test that we can only set a maximum bitrate for a fixed-rate codec
1015 // if it's bigger than the fixed rate.
1016
1017 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -07001018 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
1019 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1020 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1021 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1022 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1023 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1024 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001025}
1026
1027TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001028 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029 const int kDesiredBitrate = 128000;
1030 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001031 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001032 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001033 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001034
Yves Gerey665174f2018-06-19 15:03:05 +02001035 EXPECT_TRUE(
1036 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001037
solenberg2100c0b2017-03-01 11:29:29 -08001038 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001039}
1040
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001041// Test that bitrate cannot be set for CBR codecs.
1042// Bitrate is ignored if it is higher than the fixed bitrate.
1043// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001044TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001045 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001046
1047 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001048 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001049 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001050
1051 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001052 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001053 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001054
1055 send_parameters_.max_bandwidth_bps = 128;
1056 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001057 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001058}
1059
skvlade0d46372016-04-07 22:59:22 -07001060// Test that the per-stream bitrate limit and the global
1061// bitrate limit both apply.
1062TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1063 EXPECT_TRUE(SetupSendStream());
1064
ossu20a4b3f2017-04-27 02:08:52 -07001065 // opus, default bitrate == 32000.
1066 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001067 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1068 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1069 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1070
1071 // CBR codecs allow both maximums to exceed the bitrate.
1072 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1073 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1074 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1075 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1076
1077 // CBR codecs don't allow per stream maximums to be too low.
1078 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1079 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1080}
1081
1082// Test that an attempt to set RtpParameters for a stream that does not exist
1083// fails.
1084TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1085 EXPECT_TRUE(SetupChannel());
1086 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001087 channel_->GetRtpSendParameters(kSsrcX);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001088 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvlade0d46372016-04-07 22:59:22 -07001089
1090 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001091 EXPECT_FALSE(
1092 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001093}
1094
1095TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001096 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001097 // This test verifies that setting RtpParameters succeeds only if
1098 // the structure contains exactly one encoding.
1099 // TODO(skvlad): Update this test when we start supporting setting parameters
1100 // for each encoding individually.
1101
1102 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001103 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001104 // Two or more encodings should result in failure.
1105 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001106 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001107 // Zero encodings should also fail.
1108 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001109 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001110}
1111
1112// Changing the SSRC through RtpParameters is not allowed.
1113TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1114 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001115 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001116 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001117 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001118}
1119
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001120// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001121// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001122TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1123 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001124 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001125 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001126 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001127 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001128 ASSERT_EQ(1u, parameters.encodings.size());
1129 ASSERT_TRUE(parameters.encodings[0].active);
1130 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001131 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001132 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001133
1134 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001135 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001136 parameters.encodings[0].active = true;
Danil Chapovalov00c71832018-06-15 15:58:38 +02001137 parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001138 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001139 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001140}
1141
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001142// Test that SetRtpSendParameters configures the correct encoding channel for
1143// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001144TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1145 SetupForMultiSendStream();
1146 // Create send streams.
1147 for (uint32_t ssrc : kSsrcs4) {
1148 EXPECT_TRUE(
1149 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1150 }
1151 // Configure one stream to be limited by the stream config, another to be
1152 // limited by the global max, and the third one with no per-stream limit
1153 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001154 SetGlobalMaxBitrate(kOpusCodec, 32000);
1155 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1156 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001157 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1158
ossu20a4b3f2017-04-27 02:08:52 -07001159 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1160 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1161 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001162
1163 // Remove the global cap; the streams should switch to their respective
1164 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001165 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001166 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1167 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1168 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001169}
1170
Tim Haloun648d28a2018-10-18 16:52:22 -07001171// RTCRtpEncodingParameters.network_priority must be one of a few values
1172// derived from the default priority, corresponding to very-low, low, medium,
1173// or high.
1174TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParametersInvalidNetworkPriority) {
1175 EXPECT_TRUE(SetupSendStream());
1176 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
1177 EXPECT_EQ(1UL, parameters.encodings.size());
1178 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1179 parameters.encodings[0].network_priority);
1180
1181 double good_values[] = {0.5, 1.0, 2.0, 4.0};
1182 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
1183 for (auto it : good_values) {
1184 parameters.encodings[0].network_priority = it;
1185 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1186 }
1187 for (auto it : bad_values) {
1188 parameters.encodings[0].network_priority = it;
1189 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
1190 }
1191}
1192
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001193// Test that GetRtpSendParameters returns the currently configured codecs.
1194TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001195 EXPECT_TRUE(SetupSendStream());
1196 cricket::AudioSendParameters parameters;
1197 parameters.codecs.push_back(kIsacCodec);
1198 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001199 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001200
solenberg2100c0b2017-03-01 11:29:29 -08001201 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001202 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001203 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1204 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001205}
1206
Florent Castellidacec712018-05-24 16:24:21 +02001207// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
1208TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) {
1209 cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcX);
1210 params.cname = "rtcpcname";
1211 EXPECT_TRUE(SetupSendStream(params));
1212
1213 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1214 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
1215}
1216
Florent Castelliabe301f2018-06-12 18:33:49 +02001217TEST_F(WebRtcVoiceEngineTestFake,
1218 DetectRtpSendParameterHeaderExtensionsChange) {
1219 EXPECT_TRUE(SetupSendStream());
1220
1221 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1222 rtp_parameters.header_extensions.emplace_back();
1223
1224 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
1225
1226 webrtc::RTCError result =
1227 channel_->SetRtpSendParameters(kSsrcX, rtp_parameters);
1228 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
1229}
1230
deadbeefcb443432016-12-12 11:12:36 -08001231// Test that GetRtpSendParameters returns an SSRC.
1232TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1233 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001234 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001235 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001236 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001237}
1238
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001239// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001240TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001241 EXPECT_TRUE(SetupSendStream());
1242 cricket::AudioSendParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001245 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001246
solenberg2100c0b2017-03-01 11:29:29 -08001247 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001248
1249 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001250 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001251
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001253 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1254 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001255}
1256
minyuececec102017-03-27 13:04:25 -07001257// Test that max_bitrate_bps in send stream config gets updated correctly when
1258// SetRtpSendParameters is called.
1259TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1260 webrtc::test::ScopedFieldTrials override_field_trials(
1261 "WebRTC-Audio-SendSideBwe/Enabled/");
1262 EXPECT_TRUE(SetupSendStream());
1263 cricket::AudioSendParameters send_parameters;
1264 send_parameters.codecs.push_back(kOpusCodec);
1265 SetSendParameters(send_parameters);
1266
1267 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1268 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1269 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1270
1271 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001272 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001273 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001274
1275 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1276 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1277}
1278
Seth Hampson24722b32017-12-22 09:36:42 -08001279// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1280// a value <= 0, setting the parameters returns false.
1281TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1282 EXPECT_TRUE(SetupSendStream());
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1284 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1285 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1286 rtp_parameters.encodings[0].bitrate_priority);
1287
1288 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001289 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001290 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001291 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001292}
1293
1294// Test that the bitrate_priority in the send stream config gets updated when
1295// SetRtpSendParameters is set for the VoiceMediaChannel.
1296TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1297 EXPECT_TRUE(SetupSendStream());
1298 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1299
1300 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1301 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1302 rtp_parameters.encodings[0].bitrate_priority);
1303 double new_bitrate_priority = 2.0;
1304 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001305 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001306
1307 // The priority should get set for both the audio channel's rtp parameters
1308 // and the audio send stream's audio config.
1309 EXPECT_EQ(
1310 new_bitrate_priority,
1311 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1312 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1313}
1314
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001315// Test that GetRtpReceiveParameters returns the currently configured codecs.
1316TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1317 EXPECT_TRUE(SetupRecvStream());
1318 cricket::AudioRecvParameters parameters;
1319 parameters.codecs.push_back(kIsacCodec);
1320 parameters.codecs.push_back(kPcmuCodec);
1321 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1322
1323 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001324 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001325 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1326 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1327 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1328}
1329
deadbeefcb443432016-12-12 11:12:36 -08001330// Test that GetRtpReceiveParameters returns an SSRC.
1331TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1332 EXPECT_TRUE(SetupRecvStream());
1333 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001334 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001335 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001336 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001337}
1338
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001339// Test that if we set/get parameters multiple times, we get the same results.
1340TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1341 EXPECT_TRUE(SetupRecvStream());
1342 cricket::AudioRecvParameters parameters;
1343 parameters.codecs.push_back(kIsacCodec);
1344 parameters.codecs.push_back(kPcmuCodec);
1345 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1346
1347 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001348 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001349
1350 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001351 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001352
1353 // ... And this shouldn't change the params returned by
1354 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001355 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1356 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001357}
1358
deadbeef3bc15102017-04-20 19:25:07 -07001359// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1360// aren't signaled. It should return an empty "RtpEncodingParameters" when
1361// configured to receive an unsignaled stream and no packets have been received
1362// yet, and start returning the SSRC once a packet has been received.
1363TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1364 ASSERT_TRUE(SetupChannel());
1365 // Call necessary methods to configure receiving a default stream as
1366 // soon as it arrives.
1367 cricket::AudioRecvParameters parameters;
1368 parameters.codecs.push_back(kIsacCodec);
1369 parameters.codecs.push_back(kPcmuCodec);
1370 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1371
1372 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1373 // stream. Should return nothing.
1374 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1375
1376 // Set a sink for an unsignaled stream.
1377 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1378 // Value of "0" means "unsignaled stream".
1379 channel_->SetRawAudioSink(0, std::move(fake_sink));
1380
1381 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1382 // in this method means "unsignaled stream".
1383 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1384 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1385 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1386
1387 // Receive PCMU packet (SSRC=1).
1388 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1389
1390 // The |ssrc| member should still be unset.
1391 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1392 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1393 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1394}
1395
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396// Test that we apply codecs properly.
1397TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001398 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 cricket::AudioSendParameters parameters;
1400 parameters.codecs.push_back(kIsacCodec);
1401 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001402 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001404 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1407 EXPECT_EQ(96, send_codec_spec.payload_type);
1408 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1409 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1410 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001411 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001412 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413}
1414
ossu20a4b3f2017-04-27 02:08:52 -07001415// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1416// AudioSendStream.
1417TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001418 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001419 cricket::AudioSendParameters parameters;
1420 parameters.codecs.push_back(kIsacCodec);
1421 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001422 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001423 parameters.codecs[0].id = 96;
1424 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001425 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001426 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001427 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001428 // Calling SetSendCodec again with same codec which is already set.
1429 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001430 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001431 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001432}
1433
ossu20a4b3f2017-04-27 02:08:52 -07001434// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1435// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001436
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001437// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001439 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 cricket::AudioSendParameters parameters;
1441 parameters.codecs.push_back(kOpusCodec);
1442 parameters.codecs[0].bitrate = 0;
1443 parameters.codecs[0].clockrate = 50000;
1444 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445}
1446
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001447// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].bitrate = 0;
1453 parameters.codecs[0].channels = 0;
1454 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455}
1456
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001457// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001459 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001460 cricket::AudioSendParameters parameters;
1461 parameters.codecs.push_back(kOpusCodec);
1462 parameters.codecs[0].bitrate = 0;
1463 parameters.codecs[0].channels = 0;
1464 parameters.codecs[0].params["stereo"] = "1";
1465 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466}
1467
1468// Test that if channel is 1 for opus and there's no stereo, we fail.
1469TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001470 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 cricket::AudioSendParameters parameters;
1472 parameters.codecs.push_back(kOpusCodec);
1473 parameters.codecs[0].bitrate = 0;
1474 parameters.codecs[0].channels = 1;
1475 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476}
1477
1478// Test that if channel is 1 for opus and stereo=0, we fail.
1479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].bitrate = 0;
1484 parameters.codecs[0].channels = 1;
1485 parameters.codecs[0].params["stereo"] = "0";
1486 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487}
1488
1489// Test that if channel is 1 for opus and stereo=1, we fail.
1490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001491 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001492 cricket::AudioSendParameters parameters;
1493 parameters.codecs.push_back(kOpusCodec);
1494 parameters.codecs[0].bitrate = 0;
1495 parameters.codecs[0].channels = 1;
1496 parameters.codecs[0].params["stereo"] = "1";
1497 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498}
1499
ossu20a4b3f2017-04-27 02:08:52 -07001500// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001502 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 cricket::AudioSendParameters parameters;
1504 parameters.codecs.push_back(kOpusCodec);
1505 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001506 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001507 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001508}
1509
ossu20a4b3f2017-04-27 02:08:52 -07001510// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001512 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001513 cricket::AudioSendParameters parameters;
1514 parameters.codecs.push_back(kOpusCodec);
1515 parameters.codecs[0].bitrate = 0;
1516 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001517 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001518 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001519}
1520
ossu20a4b3f2017-04-27 02:08:52 -07001521// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001522TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001523 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001524 cricket::AudioSendParameters parameters;
1525 parameters.codecs.push_back(kOpusCodec);
1526 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001527 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001528 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001529 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001530 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001531
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001534 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001535}
1536
ossu20a4b3f2017-04-27 02:08:52 -07001537// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001539 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 cricket::AudioSendParameters parameters;
1541 parameters.codecs.push_back(kOpusCodec);
1542 parameters.codecs[0].bitrate = 0;
1543 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001544 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001545 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001546}
1547
ossu20a4b3f2017-04-27 02:08:52 -07001548// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001550 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001554 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001555 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001557 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001558
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001559 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001561 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001562}
1563
ossu20a4b3f2017-04-27 02:08:52 -07001564// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001570 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001571 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1572 EXPECT_EQ(111, spec.payload_type);
1573 EXPECT_EQ(96000, spec.target_bitrate_bps);
1574 EXPECT_EQ("opus", spec.format.name);
Mirko Bonadeif859e552018-05-30 15:31:29 +02001575 EXPECT_EQ(2u, spec.format.num_channels);
ossu20a4b3f2017-04-27 02:08:52 -07001576 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
ossu20a4b3f2017-04-27 02:08:52 -07001579// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001580TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001581 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001582 cricket::AudioSendParameters parameters;
1583 parameters.codecs.push_back(kOpusCodec);
1584 parameters.codecs[0].bitrate = 30000;
1585 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001587 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588}
1589
ossu20a4b3f2017-04-27 02:08:52 -07001590// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001592 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 cricket::AudioSendParameters parameters;
1594 parameters.codecs.push_back(kOpusCodec);
1595 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001597 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598}
1599
ossu20a4b3f2017-04-27 02:08:52 -07001600// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001601TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001602 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001603 cricket::AudioSendParameters parameters;
1604 parameters.codecs.push_back(kOpusCodec);
1605 parameters.codecs[0].bitrate = 30000;
1606 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001607 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001608 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001609}
1610
stefan13f1a0a2016-11-30 07:22:58 -08001611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1612 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1613 200000);
1614}
1615
1616TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1617 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1618}
1619
1620TEST_F(WebRtcVoiceEngineTestFake,
1621 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1622 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1623}
1624
1625TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1626 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1627}
1628
Yves Gerey665174f2018-06-19 15:03:05 +02001629TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001630 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1631 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001632 send_parameters_.max_bandwidth_bps = 100000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001633 // Setting max bitrate should keep previous min bitrate
1634 // Setting max bitrate should not reset start bitrate.
1635 EXPECT_CALL(*call_.GetMockTransportControllerSend(),
1636 SetSdpBitrateParameters(
1637 AllOf(Field(&BitrateConstraints::min_bitrate_bps, 100000),
1638 Field(&BitrateConstraints::start_bitrate_bps, -1),
1639 Field(&BitrateConstraints::max_bitrate_bps, 200000))));
stefan13f1a0a2016-11-30 07:22:58 -08001640 SetSendParameters(send_parameters_);
stefan13f1a0a2016-11-30 07:22:58 -08001641}
1642
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001643// Test that we can enable NACK with opus as callee.
1644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters parameters;
1647 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001648 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1649 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001650 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001651 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001652 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001653 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001654
Yves Gerey665174f2018-06-19 15:03:05 +02001655 EXPECT_TRUE(
1656 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001657}
1658
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001659// Test that we can enable NACK on receive streams.
1660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001662 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001663 cricket::AudioSendParameters parameters;
1664 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001665 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1666 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001667 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001668 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001669 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670}
1671
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672// Test that we can disable NACK on receive streams.
1673TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001674 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 cricket::AudioSendParameters parameters;
1677 parameters.codecs.push_back(kOpusCodec);
Yves Gerey665174f2018-06-19 15:03:05 +02001678 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1679 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001680 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001681 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001682
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001683 parameters.codecs.clear();
1684 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001685 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001686 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001687}
1688
1689// Test that NACK is enabled on a new receive stream.
1690TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001691 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 cricket::AudioSendParameters parameters;
1693 parameters.codecs.push_back(kIsacCodec);
1694 parameters.codecs.push_back(kCn16000Codec);
Yves Gerey665174f2018-06-19 15:03:05 +02001695 parameters.codecs[0].AddFeedbackParam(cricket::FeedbackParam(
1696 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001697 SetSendParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
solenberg2100c0b2017-03-01 11:29:29 -08001699 EXPECT_TRUE(AddRecvStream(kSsrcY));
1700 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1701 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1702 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703}
1704
stefanba4c0e42016-02-04 04:12:24 -08001705TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001706 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001707 cricket::AudioSendParameters send_parameters;
1708 send_parameters.codecs.push_back(kOpusCodec);
1709 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001711
1712 cricket::AudioRecvParameters recv_parameters;
1713 recv_parameters.codecs.push_back(kIsacCodec);
1714 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001715 EXPECT_TRUE(AddRecvStream(kSsrcX));
1716 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001717 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001718 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001719
ossudedfd282016-06-14 07:12:39 -07001720 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001721 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001722 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001723 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001724 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001725}
1726
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001727// Test that we can switch back and forth between Opus and ISAC with CN.
1728TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001729 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001730
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 cricket::AudioSendParameters opus_parameters;
1732 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001733 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001734 {
ossu20a4b3f2017-04-27 02:08:52 -07001735 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1736 EXPECT_EQ(111, spec.payload_type);
1737 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001738 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001739
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 cricket::AudioSendParameters isac_parameters;
1741 isac_parameters.codecs.push_back(kIsacCodec);
1742 isac_parameters.codecs.push_back(kCn16000Codec);
1743 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001745 {
ossu20a4b3f2017-04-27 02:08:52 -07001746 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1747 EXPECT_EQ(103, spec.payload_type);
1748 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001749 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001752 {
ossu20a4b3f2017-04-27 02:08:52 -07001753 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1754 EXPECT_EQ(111, spec.payload_type);
1755 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001756 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757}
1758
1759// Test that we handle various ways of specifying bitrate.
1760TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001761 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001762 cricket::AudioSendParameters parameters;
1763 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001765 {
ossu20a4b3f2017-04-27 02:08:52 -07001766 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1767 EXPECT_EQ(103, spec.payload_type);
1768 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1769 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001770 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001771
Yves Gerey665174f2018-06-19 15:03:05 +02001772 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001773 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001774 {
ossu20a4b3f2017-04-27 02:08:52 -07001775 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1776 EXPECT_EQ(103, spec.payload_type);
1777 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1778 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001779 }
Yves Gerey665174f2018-06-19 15:03:05 +02001780 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001782 {
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(103, spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1786 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001787 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001788
Yves Gerey665174f2018-06-19 15:03:05 +02001789 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001790 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001791 {
ossu20a4b3f2017-04-27 02:08:52 -07001792 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1793 EXPECT_EQ(0, spec.payload_type);
1794 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1795 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001796 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797
Yves Gerey665174f2018-06-19 15:03:05 +02001798 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001799 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001800 {
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(0, spec.payload_type);
1803 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1804 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001805 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001807 parameters.codecs[0] = kOpusCodec;
Yves Gerey665174f2018-06-19 15:03:05 +02001808 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001809 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001810 {
ossu20a4b3f2017-04-27 02:08:52 -07001811 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1812 EXPECT_EQ(111, spec.payload_type);
1813 EXPECT_STREQ("opus", spec.format.name.c_str());
1814 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001815 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816}
1817
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001818// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001820 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001821 cricket::AudioSendParameters parameters;
1822 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001823}
1824
1825// Test that we can set send codecs even with telephone-event codec as the first
1826// one on the list.
1827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001828 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001830 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001831 parameters.codecs.push_back(kIsacCodec);
1832 parameters.codecs.push_back(kPcmuCodec);
1833 parameters.codecs[0].id = 98; // DTMF
1834 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001836 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1837 EXPECT_EQ(96, spec.payload_type);
1838 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001839 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001840 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001841}
1842
Harald Alvestranda1f66612018-02-21 11:24:23 +01001843// Test that CanInsertDtmf() is governed by the send flag
1844TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1845 EXPECT_TRUE(SetupSendStream());
1846 cricket::AudioSendParameters parameters;
1847 parameters.codecs.push_back(kTelephoneEventCodec1);
1848 parameters.codecs.push_back(kPcmuCodec);
1849 parameters.codecs[0].id = 98; // DTMF
1850 parameters.codecs[1].id = 96;
1851 SetSendParameters(parameters);
1852 EXPECT_FALSE(channel_->CanInsertDtmf());
1853 SetSend(true);
1854 EXPECT_TRUE(channel_->CanInsertDtmf());
1855 SetSend(false);
1856 EXPECT_FALSE(channel_->CanInsertDtmf());
1857}
1858
solenberg31642aa2016-03-14 08:00:37 -07001859// Test that payload type range is limited for telephone-event codec.
1860TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001861 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001862 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001863 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001864 parameters.codecs.push_back(kIsacCodec);
1865 parameters.codecs[0].id = 0; // DTMF
1866 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001867 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001868 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001869 EXPECT_TRUE(channel_->CanInsertDtmf());
1870 parameters.codecs[0].id = 128; // DTMF
1871 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1872 EXPECT_FALSE(channel_->CanInsertDtmf());
1873 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001875 EXPECT_TRUE(channel_->CanInsertDtmf());
1876 parameters.codecs[0].id = -1; // DTMF
1877 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1878 EXPECT_FALSE(channel_->CanInsertDtmf());
1879}
1880
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001881// Test that we can set send codecs even with CN codec as the first
1882// one on the list.
1883TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001884 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001885 cricket::AudioSendParameters parameters;
1886 parameters.codecs.push_back(kCn16000Codec);
1887 parameters.codecs.push_back(kIsacCodec);
1888 parameters.codecs.push_back(kPcmuCodec);
1889 parameters.codecs[0].id = 98; // wideband CN
1890 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001892 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1893 EXPECT_EQ(96, send_codec_spec.payload_type);
1894 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001895 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896}
1897
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001898// Test that we set VAD and DTMF types correctly as caller.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kIsacCodec);
1903 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001904 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001905 parameters.codecs.push_back(kCn16000Codec);
1906 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001907 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 parameters.codecs[0].id = 96;
1909 parameters.codecs[2].id = 97; // wideband CN
1910 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001912 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1913 EXPECT_EQ(96, send_codec_spec.payload_type);
1914 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001915 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001916 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001917 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001918 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001919}
1920
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001921// Test that we set VAD and DTMF types correctly as callee.
1922TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001923 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 cricket::AudioSendParameters parameters;
1925 parameters.codecs.push_back(kIsacCodec);
1926 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001927 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 parameters.codecs.push_back(kCn16000Codec);
1929 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001930 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001931 parameters.codecs[0].id = 96;
1932 parameters.codecs[2].id = 97; // wideband CN
1933 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001934 SetSendParameters(parameters);
Yves Gerey665174f2018-06-19 15:03:05 +02001935 EXPECT_TRUE(
1936 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001937
ossu20a4b3f2017-04-27 02:08:52 -07001938 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1939 EXPECT_EQ(96, send_codec_spec.payload_type);
1940 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001941 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001942 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001943 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001944 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001945}
1946
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001947// Test that we only apply VAD if we have a CN codec that matches the
1948// send codec clockrate.
1949TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001950 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001951 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001952 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001953 parameters.codecs.push_back(kIsacCodec);
1954 parameters.codecs.push_back(kCn16000Codec);
1955 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001956 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001957 {
ossu20a4b3f2017-04-27 02:08:52 -07001958 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1959 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001960 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001961 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001962 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001963 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001964 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001965 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001966 {
ossu20a4b3f2017-04-27 02:08:52 -07001967 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1968 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001969 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001970 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001971 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001974 {
ossu20a4b3f2017-04-27 02:08:52 -07001975 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1976 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02001977 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001978 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001979 }
Brave Yao5225dd82015-03-26 07:39:19 +08001980 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001981 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001983 {
ossu20a4b3f2017-04-27 02:08:52 -07001984 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1985 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02001986 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001987 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988}
1989
1990// Test that we perform case-insensitive matching of codec names.
1991TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001992 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001993 cricket::AudioSendParameters parameters;
1994 parameters.codecs.push_back(kIsacCodec);
1995 parameters.codecs.push_back(kPcmuCodec);
1996 parameters.codecs.push_back(kCn16000Codec);
1997 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001998 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs[0].name = "iSaC";
2000 parameters.codecs[0].id = 96;
2001 parameters.codecs[2].id = 97; // wideband CN
2002 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002003 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07002004 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
2005 EXPECT_EQ(96, send_codec_spec.payload_type);
2006 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002007 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002008 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01002009 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002010 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002011}
2012
stefanba4c0e42016-02-04 04:12:24 -08002013class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2014 public:
2015 WebRtcVoiceEngineWithSendSideBweTest()
2016 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2017};
2018
2019TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2020 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002021 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002022 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002023 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2024 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2025 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002026 extension.id);
2027 return;
2028 }
2029 }
2030 FAIL() << "Transport sequence number extension not in header-extension list.";
2031}
2032
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002033// Test support for audio level header extension.
2034TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002035 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002036}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002037TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002038 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002039}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002040
solenbergd4adce42016-11-17 06:26:52 -08002041// Test support for transport sequence number header extension.
2042TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2043 TestSetSendRtpHeaderExtensions(
2044 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002045}
solenbergd4adce42016-11-17 06:26:52 -08002046TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2047 TestSetRecvRtpHeaderExtensions(
2048 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002049}
2050
solenberg1ac56142015-10-13 03:58:19 -07002051// Test that we can create a channel and start sending on it.
2052TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002053 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(send_parameters_);
2055 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002056 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002057 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002058 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002059}
2060
2061// Test that a channel will send if and only if it has a source and is enabled
2062// for sending.
2063TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002065 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002066 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002067 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002068 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2069 SetAudioSend(kSsrcX, true, &fake_source_);
2070 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2071 SetAudioSend(kSsrcX, true, nullptr);
2072 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002073}
2074
solenberg94218532016-06-16 10:53:22 -07002075// Test that a channel is muted/unmuted.
2076TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002078 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002079 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2080 SetAudioSend(kSsrcX, true, nullptr);
2081 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2082 SetAudioSend(kSsrcX, false, nullptr);
2083 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002084}
2085
solenberg6d6e7c52016-04-13 09:07:30 -07002086// Test that SetSendParameters() does not alter a stream's send state.
2087TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2088 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002090
2091 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002092 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002093 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002094
2095 // Changing RTP header extensions will recreate the AudioSendStream.
2096 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002097 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002098 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002099 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002100
2101 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002102 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002103 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002104
2105 // Changing RTP header extensions will recreate the AudioSendStream.
2106 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002107 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002108 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002109}
2110
solenberg1ac56142015-10-13 03:58:19 -07002111// Test that we can create a channel and start playing out on it.
2112TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002113 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002114 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002115 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002117 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002118 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002119}
2120
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002121// Test that we can add and remove send streams.
2122TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2123 SetupForMultiSendStream();
2124
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002126 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127
solenbergc96df772015-10-21 13:01:53 -07002128 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002129 EXPECT_TRUE(
2130 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002131 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002133 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 }
tfarina5237aaf2015-11-10 23:44:30 -08002135 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136
solenbergc96df772015-10-21 13:01:53 -07002137 // Delete the send streams.
2138 for (uint32_t ssrc : kSsrcs4) {
2139 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002140 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002141 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142 }
solenbergc96df772015-10-21 13:01:53 -07002143 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144}
2145
2146// Test SetSendCodecs correctly configure the codecs in all send streams.
2147TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2148 SetupForMultiSendStream();
2149
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002151 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002152 EXPECT_TRUE(
2153 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 }
2155
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002156 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002158 parameters.codecs.push_back(kIsacCodec);
2159 parameters.codecs.push_back(kCn16000Codec);
2160 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002161 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162
2163 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002164 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002165 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2166 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002167 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2168 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002169 EXPECT_EQ(1u, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002170 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002171 }
2172
minyue7a973442016-10-20 03:27:12 -07002173 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002174 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002175 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002176 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002177 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2178 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002179 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2180 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Danil Chapovalov00c71832018-06-15 15:58:38 +02002181 EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002182 }
2183}
2184
2185// Test we can SetSend on all send streams correctly.
2186TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2187 SetupForMultiSendStream();
2188
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002189 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002190 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002191 EXPECT_TRUE(
2192 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002193 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002194 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002195 }
2196
2197 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002198 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002199 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002200 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002201 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002202 }
2203
2204 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002205 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002206 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002207 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002208 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002209 }
2210}
2211
2212// Test we can set the correct statistics on all send streams.
2213TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2214 SetupForMultiSendStream();
2215
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002216 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002217 for (uint32_t ssrc : kSsrcs4) {
Yves Gerey665174f2018-06-19 15:03:05 +02002218 EXPECT_TRUE(
2219 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002220 }
solenberg85a04962015-10-27 03:35:21 -07002221
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002222 // Create a receive stream to check that none of the send streams end up in
2223 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002224 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002225
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002226 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002227 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002228 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002229 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002230
solenberg85a04962015-10-27 03:35:21 -07002231 // Check stats for the added streams.
2232 {
2233 cricket::VoiceMediaInfo info;
2234 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002235
solenberg85a04962015-10-27 03:35:21 -07002236 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002237 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002238 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002239 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002240 }
hbos1acfbd22016-11-17 23:43:29 -08002241 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002242
2243 // We have added one receive stream. We should see empty stats.
2244 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002245 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002246 }
solenberg1ac56142015-10-13 03:58:19 -07002247
solenberg2100c0b2017-03-01 11:29:29 -08002248 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002249 {
2250 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002251 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002252 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002253 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002254 EXPECT_EQ(0u, info.receivers.size());
2255 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002256
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002257 // Deliver a new packet - a default receive stream should be created and we
2258 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002259 {
2260 cricket::VoiceMediaInfo info;
2261 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2262 SetAudioReceiveStreamStats();
2263 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002264 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002265 EXPECT_EQ(1u, info.receivers.size());
2266 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002267 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002268 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002269}
2270
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002271// Test that we can add and remove receive streams, and do proper send/playout.
2272// We can receive on multiple streams while sending one stream.
2273TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002274 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002275
solenberg1ac56142015-10-13 03:58:19 -07002276 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002277 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002278 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002279
solenberg1ac56142015-10-13 03:58:19 -07002280 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002281 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002282 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002283 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284
solenberg1ac56142015-10-13 03:58:19 -07002285 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002287
2288 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2290 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2291 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292
2293 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002294 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002295 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002296
2297 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002298 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002299 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2300 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002301
aleloi84ef6152016-08-04 05:28:21 -07002302 // Restart playout and make sure recv streams are played out.
2303 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002304 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2305 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002306
aleloi84ef6152016-08-04 05:28:21 -07002307 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002308 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2309 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002310}
2311
wu@webrtc.org97077a32013-10-25 21:18:33 +00002312TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002313 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002314 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2315 .Times(1)
2316 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002317 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2318 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002319 send_parameters_.options.tx_agc_target_dbov = 3;
2320 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2321 send_parameters_.options.tx_agc_limiter = true;
2322 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002323 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2324 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2325 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002326 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002327}
2328
minyue6b825df2016-10-31 04:08:32 -07002329TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2330 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002331 send_parameters_.options.audio_network_adaptor = true;
2332 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002333 SetSendParameters(send_parameters_);
2334 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002335 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002336}
2337
2338TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2339 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002340 send_parameters_.options.audio_network_adaptor = true;
2341 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002342 SetSendParameters(send_parameters_);
2343 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002344 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002345 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002346 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002347 SetAudioSend(kSsrcX, true, nullptr, &options);
Danil Chapovalov00c71832018-06-15 15:58:38 +02002348 EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002349}
2350
2351TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2352 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002353 send_parameters_.options.audio_network_adaptor = true;
2354 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002355 SetSendParameters(send_parameters_);
2356 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002357 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002358 const int initial_num = call_.GetNumCreatedSendStreams();
2359 cricket::AudioOptions options;
Danil Chapovalov00c71832018-06-15 15:58:38 +02002360 options.audio_network_adaptor = absl::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002361 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2362 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002363 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002364 // AudioSendStream not expected to be recreated.
2365 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2366 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002367 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002368}
2369
michaelt6672b262017-01-11 10:17:59 -08002370class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2371 : public WebRtcVoiceEngineTestFake {
2372 public:
2373 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2374 : WebRtcVoiceEngineTestFake(
2375 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2376 "Enabled/") {}
2377};
2378
2379TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2380 EXPECT_TRUE(SetupSendStream());
2381 cricket::AudioSendParameters parameters;
2382 parameters.codecs.push_back(kOpusCodec);
2383 SetSendParameters(parameters);
2384 const int initial_num = call_.GetNumCreatedSendStreams();
2385 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2386
2387 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2388 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002389 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2390 constexpr int kMinOverheadBps =
2391 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002392
2393 constexpr int kOpusMinBitrateBps = 6000;
2394 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002395 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002396 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002397 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002398 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002399
Oskar Sundbom78807582017-11-16 11:09:55 +01002400 parameters.options.audio_network_adaptor = true;
2401 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002402 SetSendParameters(parameters);
2403
ossu11bfc532017-02-16 05:37:06 -08002404 constexpr int kMinOverheadWithAnaBps =
2405 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002406
2407 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002408 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002409
minyuececec102017-03-27 13:04:25 -07002410 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002411 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002412}
2413
minyuececec102017-03-27 13:04:25 -07002414// This test is similar to
2415// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2416// additional field trial.
2417TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2418 SetRtpSendParameterUpdatesMaxBitrate) {
2419 EXPECT_TRUE(SetupSendStream());
2420 cricket::AudioSendParameters send_parameters;
2421 send_parameters.codecs.push_back(kOpusCodec);
2422 SetSendParameters(send_parameters);
2423
2424 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2425 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2426 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2427
2428 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002429 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002430 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002431
2432 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2433#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2434 constexpr int kMinOverhead = 3333;
2435#else
2436 constexpr int kMinOverhead = 6666;
2437#endif
2438 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2439}
2440
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002442// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002444 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002445 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446}
2447
2448TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2449 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002450 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002451 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002452 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002453 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002454 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002455 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002456 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457
solenberg85a04962015-10-27 03:35:21 -07002458 // Check stats for the added streams.
2459 {
2460 cricket::VoiceMediaInfo info;
2461 EXPECT_EQ(true, channel_->GetStats(&info));
2462
2463 // We have added one send stream. We should see the stats we've set.
2464 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002465 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002466 // We have added one receive stream. We should see empty stats.
2467 EXPECT_EQ(info.receivers.size(), 1u);
Mirko Bonadeif859e552018-05-30 15:31:29 +02002468 EXPECT_EQ(info.receivers[0].ssrc(), 0u);
solenberg85a04962015-10-27 03:35:21 -07002469 }
solenberg1ac56142015-10-13 03:58:19 -07002470
solenberg566ef242015-11-06 15:34:49 -08002471 // Start sending - this affects some reported stats.
2472 {
2473 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002474 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002475 EXPECT_EQ(true, channel_->GetStats(&info));
2476 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002477 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002478 }
2479
solenberg2100c0b2017-03-01 11:29:29 -08002480 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002481 {
2482 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002484 EXPECT_EQ(true, channel_->GetStats(&info));
2485 EXPECT_EQ(1u, info.senders.size());
2486 EXPECT_EQ(0u, info.receivers.size());
2487 }
solenberg1ac56142015-10-13 03:58:19 -07002488
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002489 // Deliver a new packet - a default receive stream should be created and we
2490 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002491 {
2492 cricket::VoiceMediaInfo info;
2493 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2494 SetAudioReceiveStreamStats();
2495 EXPECT_EQ(true, channel_->GetStats(&info));
2496 EXPECT_EQ(1u, info.senders.size());
2497 EXPECT_EQ(1u, info.receivers.size());
2498 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002499 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002500 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501}
2502
2503// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002504// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002507 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2508 EXPECT_TRUE(AddRecvStream(kSsrcY));
2509 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002510}
2511
2512// Test that the local SSRC is the same on sending and receiving channels if the
2513// receive channel is created before the send channel.
2514TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002515 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002516 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002517 EXPECT_TRUE(
2518 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg2100c0b2017-03-01 11:29:29 -08002519 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2520 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002521}
2522
2523// Test that we can properly receive packets.
2524TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002525 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002526 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002528
Yves Gerey665174f2018-06-19 15:03:05 +02002529 EXPECT_TRUE(
2530 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531}
2532
2533// Test that we can properly receive packets on multiple streams.
2534TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002535 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002536 const uint32_t ssrc1 = 1;
2537 const uint32_t ssrc2 = 2;
2538 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002539 EXPECT_TRUE(AddRecvStream(ssrc1));
2540 EXPECT_TRUE(AddRecvStream(ssrc2));
2541 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002543 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002544 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002545 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002546 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002547 }
mflodman3d7db262016-04-29 00:57:13 -07002548
2549 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2550 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2551 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2552
2553 EXPECT_EQ(s1.received_packets(), 0);
2554 EXPECT_EQ(s2.received_packets(), 0);
2555 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002556
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002558 EXPECT_EQ(s1.received_packets(), 0);
2559 EXPECT_EQ(s2.received_packets(), 0);
2560 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002561
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002562 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002563 EXPECT_EQ(s1.received_packets(), 1);
2564 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2565 EXPECT_EQ(s2.received_packets(), 0);
2566 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002567
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002568 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002569 EXPECT_EQ(s1.received_packets(), 1);
2570 EXPECT_EQ(s2.received_packets(), 1);
2571 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2572 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002573
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002574 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002575 EXPECT_EQ(s1.received_packets(), 1);
2576 EXPECT_EQ(s2.received_packets(), 1);
2577 EXPECT_EQ(s3.received_packets(), 1);
2578 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002579
mflodman3d7db262016-04-29 00:57:13 -07002580 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2581 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2582 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002583}
2584
solenberg2100c0b2017-03-01 11:29:29 -08002585// Test that receiving on an unsignaled stream works (a stream is created).
2586TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002587 EXPECT_TRUE(SetupChannel());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002588 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002589
solenberg7e63ef02015-11-20 00:19:43 -08002590 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002591
Mirko Bonadeif859e552018-05-30 15:31:29 +02002592 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002593 EXPECT_TRUE(
2594 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002595}
2596
Seth Hampson5897a6e2018-04-03 11:16:33 -07002597// Tests that when we add a stream without SSRCs, but contains a stream_id
2598// that it is stored and its stream id is later used when the first packet
2599// arrives to properly create a receive stream with a sync label.
2600TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledSsrcWithSignaledStreamId) {
2601 const char kSyncLabel[] = "sync_label";
2602 EXPECT_TRUE(SetupChannel());
2603 cricket::StreamParams unsignaled_stream;
2604 unsignaled_stream.set_stream_ids({kSyncLabel});
2605 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
2606 // The stream shouldn't have been created at this point because it doesn't
2607 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02002608 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002609
2610 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2611
Mirko Bonadeif859e552018-05-30 15:31:29 +02002612 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002613 EXPECT_TRUE(
2614 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2615 EXPECT_EQ(kSyncLabel, GetRecvStream(kSsrc1).GetConfig().sync_group);
2616
2617 // Removing the unsignaled stream clears the cached parameters. If a new
2618 // default unsignaled receive stream is created it will not have a sync group.
2619 channel_->RemoveRecvStream(0);
2620 channel_->RemoveRecvStream(kSsrc1);
2621
2622 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2623
Mirko Bonadeif859e552018-05-30 15:31:29 +02002624 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07002625 EXPECT_TRUE(
2626 GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
2627 EXPECT_TRUE(GetRecvStream(kSsrc1).GetConfig().sync_group.empty());
2628}
2629
solenberg2100c0b2017-03-01 11:29:29 -08002630// Test that receiving N unsignaled stream works (streams will be created), and
2631// that packets are forwarded to them all.
2632TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002633 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002634 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002635 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2636
solenberg2100c0b2017-03-01 11:29:29 -08002637 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002638 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002639 rtc::SetBE32(&packet[8], ssrc);
2640 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002641
solenberg2100c0b2017-03-01 11:29:29 -08002642 // Verify we have one new stream for each loop iteration.
2643 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002644 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2645 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002646 }
mflodman3d7db262016-04-29 00:57:13 -07002647
solenberg2100c0b2017-03-01 11:29:29 -08002648 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002649 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002650 rtc::SetBE32(&packet[8], ssrc);
2651 DeliverPacket(packet, sizeof(packet));
2652
solenbergebb349d2017-03-13 05:46:15 -07002653 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002654 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2655 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2656 }
2657
2658 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2659 constexpr uint32_t kAnotherSsrc = 667;
2660 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002661 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002662
2663 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002664 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002665 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002666 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002667 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2668 EXPECT_EQ(2, streams[i]->received_packets());
2669 }
2670 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2671 EXPECT_EQ(1, streams[i]->received_packets());
2672 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002673 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002674}
2675
solenberg2100c0b2017-03-01 11:29:29 -08002676// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002677// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002678TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002679 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002680 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002681 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2682
2683 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002684 const uint32_t signaled_ssrc = 1;
2685 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002686 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002687 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002688 EXPECT_TRUE(
2689 GetRecvStream(signaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002690 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002691
2692 // Note that the first unknown SSRC cannot be 0, because we only support
2693 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002694 const uint32_t unsignaled_ssrc = 7011;
2695 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002696 DeliverPacket(packet, sizeof(packet));
Yves Gerey665174f2018-06-19 15:03:05 +02002697 EXPECT_TRUE(
2698 GetRecvStream(unsignaled_ssrc).VerifyLastPacket(packet, sizeof(packet)));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002699 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002700
2701 DeliverPacket(packet, sizeof(packet));
2702 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2703
2704 rtc::SetBE32(&packet[8], signaled_ssrc);
2705 DeliverPacket(packet, sizeof(packet));
2706 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002707 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002708}
2709
solenberg4904fb62017-02-17 12:01:14 -08002710// Two tests to verify that adding a receive stream with the same SSRC as a
2711// previously added unsignaled stream will only recreate underlying stream
2712// objects if the stream parameters have changed.
2713TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2714 EXPECT_TRUE(SetupChannel());
2715
2716 // Spawn unsignaled stream with SSRC=1.
2717 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002718 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002719 EXPECT_TRUE(
2720 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002721
2722 // Verify that the underlying stream object in Call is not recreated when a
2723 // stream with SSRC=1 is added.
2724 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002725 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002726 int audio_receive_stream_id = streams.front()->id();
2727 EXPECT_TRUE(AddRecvStream(1));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002728 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002729 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2730}
2731
2732TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2733 EXPECT_TRUE(SetupChannel());
2734
2735 // Spawn unsignaled stream with SSRC=1.
2736 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002737 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02002738 EXPECT_TRUE(
2739 GetRecvStream(1).VerifyLastPacket(kPcmuFrame, sizeof(kPcmuFrame)));
solenberg4904fb62017-02-17 12:01:14 -08002740
2741 // Verify that the underlying stream object in Call *is* recreated when a
2742 // stream with SSRC=1 is added, and which has changed stream parameters.
2743 const auto& streams = call_.GetAudioReceiveStreams();
Mirko Bonadeif859e552018-05-30 15:31:29 +02002744 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002745 int audio_receive_stream_id = streams.front()->id();
2746 cricket::StreamParams stream_params;
2747 stream_params.ssrcs.push_back(1);
Seth Hampson845e8782018-03-02 11:34:10 -08002748 stream_params.set_stream_ids({"stream_id"});
solenberg4904fb62017-02-17 12:01:14 -08002749 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
Mirko Bonadeif859e552018-05-30 15:31:29 +02002750 EXPECT_EQ(1u, streams.size());
solenberg4904fb62017-02-17 12:01:14 -08002751 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2752}
2753
solenberg1ac56142015-10-13 03:58:19 -07002754// Test that AddRecvStream creates new stream.
2755TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002756 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002757 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758}
2759
2760// Test that after adding a recv stream, we do not decode more codecs than
2761// those previously passed into SetRecvCodecs.
2762TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002763 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002764 cricket::AudioRecvParameters parameters;
2765 parameters.codecs.push_back(kIsacCodec);
2766 parameters.codecs.push_back(kPcmuCodec);
2767 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002768 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002769 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2770 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2771 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002772}
2773
2774// Test that we properly clean up any streams that were added, even if
2775// not explicitly removed.
2776TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002777 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002778 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002779 EXPECT_TRUE(AddRecvStream(1));
2780 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002781
Mirko Bonadeif859e552018-05-30 15:31:29 +02002782 EXPECT_EQ(1u, call_.GetAudioSendStreams().size());
2783 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002784 delete channel_;
2785 channel_ = NULL;
Mirko Bonadeif859e552018-05-30 15:31:29 +02002786 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
2787 EXPECT_EQ(0u, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788}
2789
wu@webrtc.org78187522013-10-07 23:32:02 +00002790TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002791 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002792 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002793}
2794
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002795TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002796 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002797 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002798 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002799}
2800
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002801// Test the InsertDtmf on default send stream as caller.
2802TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002803 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804}
2805
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002806// Test the InsertDtmf on default send stream as callee
2807TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002808 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002809}
2810
2811// Test the InsertDtmf on specified send stream as caller.
2812TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002813 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002814}
2815
2816// Test the InsertDtmf on specified send stream as callee.
2817TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002818 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002819}
2820
Johannes Kron9190b822018-10-29 11:22:05 +01002821// Test propagation of extmap allow mixed setting.
2822TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
2823 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2824}
2825TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
2826 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2827}
2828TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
2829 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2830}
2831TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
2832 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2833}
2834
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002835TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002837 EXPECT_TRUE(AddRecvStream(kSsrcY));
Yves Gerey665174f2018-06-19 15:03:05 +02002838 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2839 .Times(9)
2840 .WillRepeatedly(Return(false));
2841 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2842 .Times(4)
2843 .WillRepeatedly(Return(false));
2844 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2845 .Times(2)
2846 .WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002847
Mirko Bonadeif859e552018-05-30 15:31:29 +02002848 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002849 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002850
solenberg246b8172015-12-08 09:50:23 -08002851 // Nothing set in AudioOptions, so everything should be as default.
2852 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002853 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002854 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002855 EXPECT_TRUE(IsHighPassFilterEnabled());
Sam Zackrissonba502232019-01-04 10:36:48 +01002856 EXPECT_TRUE(IsTypingDetectionEnabled());
Mirko Bonadeif859e552018-05-30 15:31:29 +02002857 EXPECT_EQ(50u, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002858 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002859
Sam Zackrissonba502232019-01-04 10:36:48 +01002860 // Turn typing detection off.
2861 send_parameters_.options.typing_detection = false;
2862 SetSendParameters(send_parameters_);
2863 EXPECT_FALSE(IsTypingDetectionEnabled());
2864
2865 // Leave typing detection unchanged, but non-default.
2866 send_parameters_.options.typing_detection = absl::nullopt;
2867 SetSendParameters(send_parameters_);
2868 EXPECT_FALSE(IsTypingDetectionEnabled());
2869
2870 // Turn typing detection on.
2871 send_parameters_.options.typing_detection = true;
2872 SetSendParameters(send_parameters_);
2873 EXPECT_TRUE(IsTypingDetectionEnabled());
2874
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002875 // Turn echo cancellation off
Oskar Sundbom78807582017-11-16 11:09:55 +01002876 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002877 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002878 EXPECT_FALSE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
2880 // Turn echo cancellation back on, with settings, and make sure
2881 // nothing else changed.
Oskar Sundbom78807582017-11-16 11:09:55 +01002882 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002883 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002884 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002885
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002886 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2887 // control.
Oskar Sundbom78807582017-11-16 11:09:55 +01002888 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002889 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002890 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002891
2892 // Turn off echo cancellation and delay agnostic aec.
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 send_parameters_.options.delay_agnostic_aec = false;
2894 send_parameters_.options.extended_filter_aec = false;
2895 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002896 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002897 EXPECT_FALSE(IsEchoCancellationEnabled());
solenberg76377c52017-02-21 00:54:31 -08002898
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002899 // Turning delay agnostic aec back on should also turn on echo cancellation.
Oskar Sundbom78807582017-11-16 11:09:55 +01002900 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002901 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002902 EXPECT_TRUE(IsEchoCancellationEnabled());
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002903
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002904 // Turn off AGC
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002905 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002907 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002908 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002909 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
2911 // Turn AGC back on
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002912 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002914 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002915 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002916 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002918 // Turn off other options.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002919 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002920 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002921 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002922 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002923 send_parameters_.options.noise_suppression = false;
2924 send_parameters_.options.highpass_filter = false;
Oskar Sundbom78807582017-11-16 11:09:55 +01002925 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002926 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002927 EXPECT_TRUE(IsEchoCancellationEnabled());
peah8271d042016-11-22 07:24:52 -08002928 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929
solenberg1ac56142015-10-13 03:58:19 -07002930 // Set options again to ensure it has no impact.
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002931 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002932 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002933 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002934 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002935 SetSendParameters(send_parameters_);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002936 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937}
2938
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002939TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002940 EXPECT_TRUE(SetupSendStream());
Yves Gerey665174f2018-06-19 15:03:05 +02002941 EXPECT_CALL(adm_, BuiltInAECIsAvailable())
2942 .Times(8)
2943 .WillRepeatedly(Return(false));
2944 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2945 .Times(8)
2946 .WillRepeatedly(Return(false));
2947 EXPECT_CALL(adm_, BuiltInNSIsAvailable())
2948 .Times(8)
2949 .WillRepeatedly(Return(false));
2950 EXPECT_CALL(adm_, RecordingIsInitialized())
2951 .Times(2)
2952 .WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002953 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2954 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002955 webrtc::AudioProcessing::Config apm_config;
2956 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07002957 .WillRepeatedly(ReturnPointee(&apm_config));
2958 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07002959 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002960 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002961
kwiberg686a8ef2016-02-26 03:00:35 -08002962 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002963 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2964 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2965 cricket::AudioOptions(),
2966 webrtc::CryptoOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002967 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
Sebastian Jansson84848f22018-11-16 10:40:36 +01002968 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2969 engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
2970 cricket::AudioOptions(),
2971 webrtc::CryptoOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972
2973 // Have to add a stream to make SetSend work.
2974 cricket::StreamParams stream1;
2975 stream1.ssrcs.push_back(1);
2976 channel1->AddSendStream(stream1);
2977 cricket::StreamParams stream2;
2978 stream2.ssrcs.push_back(2);
2979 channel2->AddSendStream(stream2);
2980
2981 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002982 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002983 parameters_options_all.options.echo_cancellation = true;
2984 parameters_options_all.options.auto_gain_control = true;
2985 parameters_options_all.options.noise_suppression = true;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002986 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002987 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002988 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002989 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002990 EXPECT_TRUE(channel1->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, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002993 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02002994 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002995 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996
2997 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002998 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002999 parameters_options_no_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003000 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003001 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003002 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003003 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003004 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003005 EXPECT_TRUE(IsEchoCancellationEnabled());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003007 expected_options.echo_cancellation = true;
3008 expected_options.auto_gain_control = true;
3009 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003010 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011
3012 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003013 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003014 parameters_options_no_agc.options.auto_gain_control = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003015 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003016 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003017 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003018 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003019 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003020 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003021 expected_options.echo_cancellation = true;
3022 expected_options.auto_gain_control = false;
3023 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07003024 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003026 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003027 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003028 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003029 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003030 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003031 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003033 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003034 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003035 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003036 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003037 channel1->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003038 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003039
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003040 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003041 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003042 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003043 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003044 channel2->SetSend(true);
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003045 EXPECT_TRUE(IsEchoCancellationEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003048 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3049 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01003050 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
3051 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003052 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003053 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01003054 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08003055 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003056 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Sam Zackrisson7988e5c2018-09-24 17:35:22 +02003057 EXPECT_TRUE(IsEchoCancellationEnabled());
Oskar Sundbom78807582017-11-16 11:09:55 +01003058 expected_options.echo_cancellation = true;
3059 expected_options.auto_gain_control = false;
3060 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07003061 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062}
3063
wu@webrtc.orgde305012013-10-31 15:40:38 +00003064// This test verifies DSCP settings are properly applied on voice media channel.
3065TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003066 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003067 cricket::FakeNetworkInterface network_interface;
3068 cricket::MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07003069 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07003070 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08003071
peahb1c9d1d2017-07-25 15:45:24 -07003072 webrtc::AudioProcessing::Config apm_config;
3073 EXPECT_CALL(*apm_, GetConfig())
peahb1c9d1d2017-07-25 15:45:24 -07003074 .WillRepeatedly(ReturnPointee(&apm_config));
3075 EXPECT_CALL(*apm_, ApplyConfig(_))
peahb1c9d1d2017-07-25 15:45:24 -07003076 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07003077 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07003078
Sebastian Jansson84848f22018-11-16 10:40:36 +01003079 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3080 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3081 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003082 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003083 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3084 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3085
3086 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003087 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3088 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3089 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003090 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07003091 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3092
3093 // Create a send stream to configure
3094 EXPECT_TRUE(
3095 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
3096 parameters = channel->GetRtpSendParameters(kSsrcZ);
3097 ASSERT_FALSE(parameters.encodings.empty());
3098
3099 // Various priorities map to various dscp values.
3100 parameters.encodings[0].network_priority = 4.0;
3101 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08003102 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07003103 parameters.encodings[0].network_priority = 0.5;
3104 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3105 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
3106
3107 // A bad priority does not change the dscp value.
3108 parameters.encodings[0].network_priority = 0.0;
3109 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrcZ, parameters).ok());
3110 EXPECT_EQ(rtc::DSCP_CS1, network_interface.dscp());
nisse51542be2016-02-12 02:27:06 -08003111
Tim Haloun6ca98362018-09-17 17:06:08 -07003112 // Packets should also self-identify their dscp in PacketOptions.
3113 const uint8_t kData[10] = {0};
3114 EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07003115 EXPECT_EQ(rtc::DSCP_CS1, network_interface.options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07003116
nisse51542be2016-02-12 02:27:06 -08003117 // Verify that setting the option to false resets the
3118 // DiffServCodePoint.
3119 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003120 channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
3121 engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
3122 webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003123 channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08003124 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3125 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3126
Anton Sukhanov98a462c2018-10-17 13:15:42 -07003127 channel->SetInterface(nullptr, nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003128}
3129
solenberg4bac9c52015-10-09 02:32:53 -07003130TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003131 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003132 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003133 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003134 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003135 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003136 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3137 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3138 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003139}
3140
solenberg2100c0b2017-03-01 11:29:29 -08003141TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003142 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003143
3144 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003145 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003146 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3147
3148 // Should remember the volume "2" which will be set on new unsignaled streams,
3149 // and also set the gain to 2 on existing unsignaled streams.
3150 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3151 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3152
3153 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3154 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3155 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3156 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3157 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3158 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3159
3160 // Setting gain with SSRC=0 should affect all unsignaled streams.
3161 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003162 if (kMaxUnsignaledRecvStreams > 1) {
3163 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3164 }
solenberg2100c0b2017-03-01 11:29:29 -08003165 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3166
3167 // Setting gain on an individual stream affects only that.
3168 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003169 if (kMaxUnsignaledRecvStreams > 1) {
3170 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3171 }
solenberg2100c0b2017-03-01 11:29:29 -08003172 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003173}
3174
Seth Hampson845e8782018-03-02 11:34:10 -08003175TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromStreamId) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003176 const uint32_t kAudioSsrc = 123;
Seth Hampson845e8782018-03-02 11:34:10 -08003177 const std::string kStreamId = "AvSyncLabel";
pbos8fc7fa72015-07-15 08:02:58 -07003178
solenbergff976312016-03-30 23:28:51 -07003179 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003180 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08003181 sp.set_stream_ids({kStreamId});
pbos8fc7fa72015-07-15 08:02:58 -07003182 // Creating two channels to make sure that sync label is set properly for both
3183 // the default voice channel and following ones.
3184 EXPECT_TRUE(channel_->AddRecvStream(sp));
3185 sp.ssrcs[0] += 1;
3186 EXPECT_TRUE(channel_->AddRecvStream(sp));
3187
Mirko Bonadeif859e552018-05-30 15:31:29 +02003188 ASSERT_EQ(2u, call_.GetAudioReceiveStreams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08003189 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003190 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003191 << "SyncGroup should be set based on stream id";
3192 EXPECT_EQ(kStreamId,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003193 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
Seth Hampson845e8782018-03-02 11:34:10 -08003194 << "SyncGroup should be set based on stream id";
pbos8fc7fa72015-07-15 08:02:58 -07003195}
3196
solenberg3a941542015-11-16 07:34:50 -08003197// TODO(solenberg): Remove, once recv streams are configured through Call.
3198// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003199TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003200 // Test that setting the header extensions results in the expected state
3201 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003202 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003203 ssrcs.push_back(223);
3204 ssrcs.push_back(224);
3205
solenbergff976312016-03-30 23:28:51 -07003206 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003207 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003208 for (uint32_t ssrc : ssrcs) {
Yves Gerey665174f2018-06-19 15:03:05 +02003209 EXPECT_TRUE(
3210 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc)));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003211 }
3212
Mirko Bonadeif859e552018-05-30 15:31:29 +02003213 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003214 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003215 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003216 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003217 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003218 }
3219
3220 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003221 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003222 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003223 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003224 channel_->SetRecvParameters(recv_parameters);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003225 EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003226 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003227 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003228 EXPECT_NE(nullptr, s);
3229 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003230 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3231 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003232 for (const auto& s_ext : s_exts) {
3233 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003234 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003235 }
3236 }
3237 }
3238 }
3239
3240 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003241 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003242 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003243 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003244 EXPECT_NE(nullptr, s);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003245 EXPECT_EQ(0u, s->GetConfig().rtp.extensions.size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003246 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003247}
3248
3249TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3250 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003251 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003252 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003253 static const unsigned char kRtcp[] = {
Yves Gerey665174f2018-06-19 15:03:05 +02003254 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3255 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
jbaucheec21bd2016-03-20 06:15:43 -07003257 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258
solenbergff976312016-03-30 23:28:51 -07003259 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003260 cricket::WebRtcVoiceMediaChannel* media_channel =
3261 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003262 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003263 EXPECT_TRUE(media_channel->AddRecvStream(
3264 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3265
Mirko Bonadeif859e552018-05-30 15:31:29 +02003266 EXPECT_EQ(1u, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003267 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003268 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269 EXPECT_EQ(0, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003270 channel_->OnPacketReceived(&kPcmuPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003271 EXPECT_EQ(1, s->received_packets());
Niels Möllere6933812018-11-05 13:01:41 +01003272 channel_->OnRtcpReceived(&kRtcpPacket, /* packet_time_us */ -1);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003273 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003274}
Minyue2013aec2015-05-13 14:14:42 +02003275
solenberg0a617e22015-10-20 15:49:38 -07003276// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003277// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003278TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003279 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003280 EXPECT_TRUE(AddRecvStream(kSsrcY));
3281 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003282 EXPECT_TRUE(
3283 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcZ)));
solenberg2100c0b2017-03-01 11:29:29 -08003284 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3285 EXPECT_TRUE(AddRecvStream(kSsrcW));
3286 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003287}
3288
solenberg7602aab2016-11-14 11:30:07 -08003289TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3290 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003292 EXPECT_TRUE(
3293 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg2100c0b2017-03-01 11:29:29 -08003294 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3295 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3296 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Yves Gerey665174f2018-06-19 15:03:05 +02003297 EXPECT_TRUE(
3298 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcW)));
solenberg2100c0b2017-03-01 11:29:29 -08003299 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3300 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003301}
stefan658910c2015-09-03 05:48:32 -07003302
deadbeef884f5852016-01-15 09:20:04 -08003303TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003304 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003305 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3306 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003307
3308 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003309 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3310 EXPECT_TRUE(AddRecvStream(kSsrcX));
3311 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003312
3313 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003314 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3315 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003316
3317 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003318 channel_->SetRawAudioSink(kSsrcX, nullptr);
3319 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003320}
3321
solenberg2100c0b2017-03-01 11:29:29 -08003322TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003323 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003324 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3325 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003326 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3327 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003328
3329 // Should be able to set a default sink even when no stream exists.
3330 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3331
solenberg2100c0b2017-03-01 11:29:29 -08003332 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3333 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003334 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003335 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003336
3337 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003338 channel_->SetRawAudioSink(kSsrc0, nullptr);
3339 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003340
3341 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003342 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3343 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003344
3345 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003346 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003347 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3349
3350 // Spawn another unsignaled stream - it should be assigned the default sink
3351 // and the previous unsignaled stream should lose it.
3352 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3353 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3354 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3355 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003356 if (kMaxUnsignaledRecvStreams > 1) {
3357 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3358 }
solenberg2100c0b2017-03-01 11:29:29 -08003359 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3360
3361 // Reset the default sink - the second unsignaled stream should lose it.
3362 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003363 if (kMaxUnsignaledRecvStreams > 1) {
3364 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3365 }
solenberg2100c0b2017-03-01 11:29:29 -08003366 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3367
3368 // Try setting the default sink while two streams exists.
3369 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003370 if (kMaxUnsignaledRecvStreams > 1) {
3371 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3372 }
solenberg2100c0b2017-03-01 11:29:29 -08003373 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3374
3375 // Try setting the sink for the first unsignaled stream using its known SSRC.
3376 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003377 if (kMaxUnsignaledRecvStreams > 1) {
3378 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3379 }
solenberg2100c0b2017-03-01 11:29:29 -08003380 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003381 if (kMaxUnsignaledRecvStreams > 1) {
3382 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3383 }
deadbeef884f5852016-01-15 09:20:04 -08003384}
3385
skvlad7a43d252016-03-22 15:32:27 -07003386// Test that, just like the video channel, the voice channel communicates the
3387// network state to the call.
3388TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003389 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003390
3391 EXPECT_EQ(webrtc::kNetworkUp,
3392 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3393 EXPECT_EQ(webrtc::kNetworkUp,
3394 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3395
3396 channel_->OnReadyToSend(false);
3397 EXPECT_EQ(webrtc::kNetworkDown,
3398 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3399 EXPECT_EQ(webrtc::kNetworkUp,
3400 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3401
3402 channel_->OnReadyToSend(true);
3403 EXPECT_EQ(webrtc::kNetworkUp,
3404 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3405 EXPECT_EQ(webrtc::kNetworkUp,
3406 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3407}
3408
aleloi18e0b672016-10-04 02:45:47 -07003409// Test that playout is still started after changing parameters
3410TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3411 SetupRecvStream();
3412 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003413 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003414
3415 // Changing RTP header extensions will recreate the AudioReceiveStream.
3416 cricket::AudioRecvParameters parameters;
3417 parameters.extensions.push_back(
3418 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3419 channel_->SetRecvParameters(parameters);
3420
solenberg2100c0b2017-03-01 11:29:29 -08003421 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003422}
3423
Zhi Huangfa266ef2017-12-13 10:27:46 -08003424// Tests when GetSources is called with non-existing ssrc, it will return an
3425// empty list of RtpSource without crashing.
3426TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3427 // Setup an recv stream with |kSsrcX|.
3428 SetupRecvStream();
3429 cricket::WebRtcVoiceMediaChannel* media_channel =
3430 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3431 // Call GetSources with |kSsrcY| which doesn't exist.
3432 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3433 EXPECT_EQ(0u, sources.size());
3434}
3435
stefan658910c2015-09-03 05:48:32 -07003436// Tests that the library initializes and shuts down properly.
3437TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003438 // If the VoiceEngine wants to gather available codecs early, that's fine but
3439 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003440 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003441 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003442 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003443 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003444 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003445 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003446 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003447 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003448 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003449 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003450 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3451 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3452 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003453 EXPECT_TRUE(channel != nullptr);
3454 delete channel;
solenbergff976312016-03-30 23:28:51 -07003455}
stefan658910c2015-09-03 05:48:32 -07003456
solenbergff976312016-03-30 23:28:51 -07003457// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003458TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3459 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003460 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003461 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003462 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003463 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003464 {
peaha9cc40b2017-06-29 08:32:09 -07003465 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003466 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003467 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003468 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003469 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003470 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003471 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003472 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003473 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
Sebastian Jansson84848f22018-11-16 10:40:36 +01003474 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3475 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3476 webrtc::CryptoOptions());
solenbergff976312016-03-30 23:28:51 -07003477 EXPECT_TRUE(channel != nullptr);
3478 delete channel;
3479 }
stefan658910c2015-09-03 05:48:32 -07003480}
3481
ossu20a4b3f2017-04-27 02:08:52 -07003482// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3483TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003484 // TODO(ossu): Why are the payload types of codecs with non-static payload
3485 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003486 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003487 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003488 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003489 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003490 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003491 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003492 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003493 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003494 auto is_codec = [&codec](const char* name, int clockrate = 0) {
Niels Möller2edab4c2018-10-22 09:48:08 +02003495 return absl::EqualsIgnoreCase(codec.name, name) &&
ossu20a4b3f2017-04-27 02:08:52 -07003496 (clockrate == 0 || codec.clockrate == clockrate);
3497 };
3498 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003499 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003500 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003501 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003502 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003503 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003504 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003505 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003506 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003507 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003508 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003509 EXPECT_EQ(126, codec.id);
Yves Gerey665174f2018-06-19 15:03:05 +02003510 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3511 // Remove these checks once both send and receive side assigns payload
3512 // types dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003513 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003514 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003515 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003516 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003517 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003518 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003519 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003520 EXPECT_EQ(111, codec.id);
3521 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3522 EXPECT_EQ("10", codec.params.find("minptime")->second);
3523 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3524 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003525 }
3526 }
stefan658910c2015-09-03 05:48:32 -07003527}
3528
3529// Tests that VoE supports at least 32 channels
3530TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003531 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003532 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003533 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003534 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003535 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003536 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003537 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003538 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003539 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003540 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003541
3542 cricket::VoiceMediaChannel* channels[32];
Mirko Bonadeif859e552018-05-30 15:31:29 +02003543 size_t num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003544 while (num_channels < arraysize(channels)) {
Sebastian Jansson84848f22018-11-16 10:40:36 +01003545 cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
3546 call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
3547 webrtc::CryptoOptions());
stefan658910c2015-09-03 05:48:32 -07003548 if (!channel)
3549 break;
stefan658910c2015-09-03 05:48:32 -07003550 channels[num_channels++] = channel;
3551 }
3552
Mirko Bonadeif859e552018-05-30 15:31:29 +02003553 size_t expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003554 EXPECT_EQ(expected, num_channels);
3555
3556 while (num_channels > 0) {
3557 delete channels[--num_channels];
3558 }
stefan658910c2015-09-03 05:48:32 -07003559}
3560
3561// Test that we set our preferred codecs properly.
3562TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003563 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3564 // - Check that our builtin codecs are usable by Channel.
3565 // - The codecs provided by the engine is usable by Channel.
3566 // It does not check that the codecs in the RecvParameters are actually
3567 // what we sent in - though it's probably reasonable to expect so, if
3568 // SetRecvParameters returns true.
3569 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003570 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003571 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003572 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003573 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003574 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003575 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003576 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003577 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003578 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003579 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003580 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003581 cricket::AudioOptions(),
3582 webrtc::CryptoOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003583 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003584 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003585 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003586}
ossu9def8002017-02-09 05:14:32 -08003587
3588TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3589 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003590 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3591 {48000, 2, 16000, 10000, 20000}};
3592 spec1.info.allow_comfort_noise = false;
3593 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003594 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003595 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3596 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003597 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003598 specs.push_back(webrtc::AudioCodecSpec{
3599 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3600 {16000, 1, 13300}});
3601 specs.push_back(
3602 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3603 specs.push_back(
3604 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003605
ossueb1fde42017-05-02 06:46:30 -07003606 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3607 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3608 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003609 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003610 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003611 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003612 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003613
peaha9cc40b2017-06-29 08:32:09 -07003614 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003615 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003616 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003617 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003618 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003619 auto codecs = engine.recv_codecs();
Mirko Bonadeif859e552018-05-30 15:31:29 +02003620 EXPECT_EQ(11u, codecs.size());
ossu9def8002017-02-09 05:14:32 -08003621
3622 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3623 // check the actual values safely, to provide better test results.
Yves Gerey665174f2018-06-19 15:03:05 +02003624 auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
3625 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3626 if (codecs.size() > index)
3627 return codecs[index];
3628 return missing_codec;
3629 };
ossu9def8002017-02-09 05:14:32 -08003630
3631 // Ensure the general codecs are generated first and in order.
3632 for (size_t i = 0; i != specs.size(); ++i) {
3633 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3634 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3635 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3636 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3637 }
3638
3639 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003640 // supplementary codecs are ordered after the general codecs.
Yves Gerey665174f2018-06-19 15:03:05 +02003641 auto find_codec = [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3642 for (size_t i = 0; i != codecs.size(); ++i) {
3643 const cricket::AudioCodec& codec = codecs[i];
Niels Möller2edab4c2018-10-22 09:48:08 +02003644 if (absl::EqualsIgnoreCase(codec.name, format.name) &&
Yves Gerey665174f2018-06-19 15:03:05 +02003645 codec.clockrate == format.clockrate_hz &&
3646 codec.channels == format.num_channels) {
3647 return rtc::checked_cast<int>(i);
3648 }
3649 }
3650 return -1;
3651 };
ossu9def8002017-02-09 05:14:32 -08003652
3653 // Ensure all supplementary codecs are generated last. Their internal ordering
3654 // is not important.
3655 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3656 const int num_specs = static_cast<int>(specs.size());
3657 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3658 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3659 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3660 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3661 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3662 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3663 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3664}