blob: f5fc9a0e3848ec96a8ee6eaff0a8027ebe82dece [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070039using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070040using testing::ReturnPointee;
41using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070042using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000043
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020044namespace {
45
solenberg418b7d32017-06-13 00:38:27 -070046constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070047
deadbeef67cf2c12016-04-13 10:07:16 -070048const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
49const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070050const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
52const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
54const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080055const cricket::AudioCodec
56 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
57const cricket::AudioCodec
58 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
59
solenberg2100c0b2017-03-01 11:29:29 -080060const uint32_t kSsrc0 = 0;
61const uint32_t kSsrc1 = 1;
62const uint32_t kSsrcX = 0x99;
63const uint32_t kSsrcY = 0x17;
64const uint32_t kSsrcZ = 0x42;
65const uint32_t kSsrcW = 0x02;
66const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067
solenberg971cab02016-06-14 10:02:41 -070068constexpr int kRtpHistoryMs = 5000;
69
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010070constexpr webrtc::GainControl::Mode kDefaultAgcMode =
71#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
72 webrtc::GainControl::kFixedDigital;
73#else
74 webrtc::GainControl::kAdaptiveAnalog;
75#endif
76
77constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
78 webrtc::NoiseSuppression::kHigh;
79
solenberg9a5f032222017-03-15 06:14:12 -070080void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
81 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010082
83 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010084 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010085 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010086 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070087#if defined(WEBRTC_WIN)
88 EXPECT_CALL(*adm, SetPlayoutDevice(
89 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
90 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
91 .WillOnce(Return(0));
92#else
93 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
94#endif // #if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
96 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
97 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +010098#if defined(WEBRTC_WIN)
99 EXPECT_CALL(*adm, SetRecordingDevice(
100 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
101 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
102 .WillOnce(Return(0));
103#else
104 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
105#endif // #if defined(WEBRTC_WIN)
106 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
107 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
108 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700109 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
110 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
111 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100112
113 // Teardown.
114 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
115 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
116 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
117 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100118 EXPECT_CALL(*adm, Release()).Times(3)
119 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700120}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200121} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122
solenbergff976312016-03-30 23:28:51 -0700123// Tests that our stub library "works".
124TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700125 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700126 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700127 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
128 new rtc::RefCountedObject<
129 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700130 webrtc::AudioProcessing::Config apm_config;
131 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
132 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700133 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700134 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700135 {
ossuc54071d2016-08-17 02:45:41 -0700136 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700137 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100138 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700139 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700140 }
solenbergff976312016-03-30 23:28:51 -0700141}
142
deadbeef884f5852016-01-15 09:20:04 -0800143class FakeAudioSink : public webrtc::AudioSinkInterface {
144 public:
145 void OnData(const Data& audio) override {}
146};
147
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800148class FakeAudioSource : public cricket::AudioSource {
149 void SetSink(Sink* sink) override {}
150};
151
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152class WebRtcVoiceEngineTestFake : public testing::Test {
153 public:
stefanba4c0e42016-02-04 04:12:24 -0800154 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
155
156 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700157 : apm_(new rtc::RefCountedObject<
158 StrictMock<webrtc::test::MockAudioProcessing>>()),
159 apm_gc_(*apm_->gain_control()),
160 apm_ec_(*apm_->echo_cancellation()),
161 apm_ns_(*apm_->noise_suppression()),
162 apm_vd_(*apm_->voice_detection()),
163 call_(webrtc::Call::Config(&event_log_)),
skvlad11a9cbf2016-10-07 11:53:05 -0700164 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800165 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700166 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800167 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700168 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
169 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700170 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700171 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800172 // Default Options.
173 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
174 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100175 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
176 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800177 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100178 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
179 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800180 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
181 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800182 // Init does not overwrite default AGC config.
183 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
184 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
185 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800186 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
187 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700188 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800189 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700190 // factories. Those tests should probably be moved elsewhere.
191 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
192 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100193 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100194 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700195 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200196 send_parameters_.codecs.push_back(kPcmuCodec);
197 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100198
solenberg76377c52017-02-21 00:54:31 -0800199 // Default Options.
200 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 }
solenberg8189b022016-06-14 12:13:00 -0700202
solenbergff976312016-03-30 23:28:51 -0700203 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700204 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700205 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
206 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200207 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000208 }
solenberg8189b022016-06-14 12:13:00 -0700209
solenbergff976312016-03-30 23:28:51 -0700210 bool SetupRecvStream() {
211 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700212 return false;
213 }
solenberg2100c0b2017-03-01 11:29:29 -0800214 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700215 }
solenberg8189b022016-06-14 12:13:00 -0700216
solenbergff976312016-03-30 23:28:51 -0700217 bool SetupSendStream() {
218 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000219 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 }
solenberg2100c0b2017-03-01 11:29:29 -0800221 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800222 return false;
223 }
peaha9cc40b2017-06-29 08:32:09 -0700224 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800225 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 }
solenberg8189b022016-06-14 12:13:00 -0700227
228 bool AddRecvStream(uint32_t ssrc) {
229 EXPECT_TRUE(channel_);
230 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
231 }
232
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000233 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700234 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700235 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800236 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
237 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700238 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800239 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700243 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000244 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000245 }
solenberg8189b022016-06-14 12:13:00 -0700246
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200247 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 }
250
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100251 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
252 const auto* send_stream = call_.GetAudioSendStream(ssrc);
253 EXPECT_TRUE(send_stream);
254 return *send_stream;
255 }
256
deadbeef884f5852016-01-15 09:20:04 -0800257 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
258 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
259 EXPECT_TRUE(recv_stream);
260 return *recv_stream;
261 }
262
solenberg3a941542015-11-16 07:34:50 -0800263 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800264 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800265 }
266
solenberg7add0582015-11-20 09:59:34 -0800267 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800268 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800269 }
270
solenberg059fb442016-10-26 05:12:24 -0700271 void SetSend(bool enable) {
272 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700273 if (enable) {
274 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
275 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
276 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700277 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700278 }
solenberg059fb442016-10-26 05:12:24 -0700279 channel_->SetSend(enable);
280 }
281
282 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700283 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700284 ASSERT_TRUE(channel_);
285 EXPECT_TRUE(channel_->SetSendParameters(params));
286 }
287
minyue6b825df2016-10-31 04:08:32 -0700288 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
289 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700290 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700291 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700292 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700293 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700294 }
295 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700296 }
297
solenbergffbbcac2016-11-17 05:25:37 -0800298 void TestInsertDtmf(uint32_t ssrc, bool caller,
299 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700300 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000301 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700302 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000303 // send stream.
304 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800305 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000307
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700309 SetSendParameters(send_parameters_);
310 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800312 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800313 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700314 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316
317 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700318 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800319 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800321 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 }
323
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800325 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100327 // Test send.
328 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800329 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100330 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800332 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800333 EXPECT_EQ(codec.id, telephone_event.payload_type);
334 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100335 EXPECT_EQ(2, telephone_event.event_code);
336 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 }
338
339 // Test that send bandwidth is set correctly.
340 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000341 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
342 // |expected_result| is the expected result from SetMaxSendBandwidth().
343 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700344 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
345 int max_bitrate,
346 bool expected_result,
347 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200348 cricket::AudioSendParameters parameters;
349 parameters.codecs.push_back(codec);
350 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700351 if (expected_result) {
352 SetSendParameters(parameters);
353 } else {
354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
355 }
solenberg2100c0b2017-03-01 11:29:29 -0800356 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357 }
358
skvlade0d46372016-04-07 22:59:22 -0700359 // Sets the per-stream maximum bitrate limit for the specified SSRC.
360 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700361 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700362 EXPECT_EQ(1UL, parameters.encodings.size());
363
Oskar Sundbom78807582017-11-16 11:09:55 +0100364 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800365 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700366 }
367
solenberg059fb442016-10-26 05:12:24 -0700368 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700369 cricket::AudioSendParameters send_parameters;
370 send_parameters.codecs.push_back(codec);
371 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700372 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700373 }
374
ossu20a4b3f2017-04-27 02:08:52 -0700375 void CheckSendCodecBitrate(int32_t ssrc,
376 const char expected_name[],
377 int expected_bitrate) {
378 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
379 EXPECT_EQ(expected_name, spec->format.name);
380 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700381 }
382
ossu20a4b3f2017-04-27 02:08:52 -0700383 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
384 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700385 }
386
minyue6b825df2016-10-31 04:08:32 -0700387 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
388 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
389 }
390
skvlade0d46372016-04-07 22:59:22 -0700391 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
392 int global_max,
393 int stream_max,
394 bool expected_result,
395 int expected_codec_bitrate) {
396 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800397 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700398
399 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700400 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800401 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700402
403 // Verify that reading back the parameters gives results
404 // consistent with the Set() result.
405 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800406 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700407 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
408 EXPECT_EQ(expected_result ? stream_max : -1,
409 resulting_parameters.encodings[0].max_bitrate_bps);
410
411 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800412 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700413 }
414
stefan13f1a0a2016-11-30 07:22:58 -0800415 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
416 int expected_min_bitrate_bps,
417 const char* start_bitrate_kbps,
418 int expected_start_bitrate_bps,
419 const char* max_bitrate_kbps,
420 int expected_max_bitrate_bps) {
421 EXPECT_TRUE(SetupSendStream());
422 auto& codecs = send_parameters_.codecs;
423 codecs.clear();
424 codecs.push_back(kOpusCodec);
425 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
426 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
427 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
428 SetSendParameters(send_parameters_);
429
430 EXPECT_EQ(expected_min_bitrate_bps,
431 call_.GetConfig().bitrate_config.min_bitrate_bps);
432 EXPECT_EQ(expected_start_bitrate_bps,
433 call_.GetConfig().bitrate_config.start_bitrate_bps);
434 EXPECT_EQ(expected_max_bitrate_bps,
435 call_.GetConfig().bitrate_config.max_bitrate_bps);
436 }
437
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000438 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700439 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000440
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000441 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800442 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000443
444 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700445 send_parameters_.extensions.push_back(
446 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700447 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800448 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200451 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700452 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800453 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000454
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000455 // Ensure extension is set properly.
456 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700457 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700458 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800459 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
460 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
461 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
solenberg7add0582015-11-20 09:59:34 -0800463 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800465 cricket::StreamParams::CreateLegacy(kSsrcY)));
466 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
467 call_.GetAudioSendStream(kSsrcY));
468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000471
472 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200473 send_parameters_.codecs.push_back(kPcmuCodec);
474 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700475 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800476 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
477 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000478 }
479
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000480 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700481 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000483 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485
486 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700487 recv_parameters_.extensions.push_back(
488 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800489 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000492 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800493 recv_parameters_.extensions.clear();
494 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000497 // Ensure extension is set properly.
498 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700499 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800500 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
502 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
503 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
solenberg7add0582015-11-20 09:59:34 -0800505 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800506 EXPECT_TRUE(AddRecvStream(kSsrcY));
507 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
508 call_.GetAudioReceiveStream(kSsrcY));
509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000512
513 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800514 recv_parameters_.extensions.clear();
515 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800516 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
517 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000518 }
519
solenberg85a04962015-10-27 03:35:21 -0700520 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
521 webrtc::AudioSendStream::Stats stats;
522 stats.local_ssrc = 12;
523 stats.bytes_sent = 345;
524 stats.packets_sent = 678;
525 stats.packets_lost = 9012;
526 stats.fraction_lost = 34.56f;
527 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100528 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700529 stats.ext_seqnum = 789;
530 stats.jitter_ms = 12;
531 stats.rtt_ms = 345;
532 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100533 stats.apm_statistics.delay_median_ms = 234;
534 stats.apm_statistics.delay_standard_deviation_ms = 567;
535 stats.apm_statistics.echo_return_loss = 890;
536 stats.apm_statistics.echo_return_loss_enhancement = 1234;
537 stats.apm_statistics.residual_echo_likelihood = 0.432f;
538 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100539 stats.ana_statistics.bitrate_action_counter = 321;
540 stats.ana_statistics.channel_action_counter = 432;
541 stats.ana_statistics.dtx_action_counter = 543;
542 stats.ana_statistics.fec_action_counter = 654;
543 stats.ana_statistics.frame_length_increase_counter = 765;
544 stats.ana_statistics.frame_length_decrease_counter = 876;
545 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700546 stats.typing_noise_detected = true;
547 return stats;
548 }
549 void SetAudioSendStreamStats() {
550 for (auto* s : call_.GetAudioSendStreams()) {
551 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200552 }
solenberg85a04962015-10-27 03:35:21 -0700553 }
solenberg566ef242015-11-06 15:34:49 -0800554 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
555 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700556 const auto stats = GetAudioSendStreamStats();
557 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
558 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
559 EXPECT_EQ(info.packets_sent, stats.packets_sent);
560 EXPECT_EQ(info.packets_lost, stats.packets_lost);
561 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
562 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800563 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700564 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
565 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
566 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
567 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100568 EXPECT_EQ(info.apm_statistics.delay_median_ms,
569 stats.apm_statistics.delay_median_ms);
570 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
571 stats.apm_statistics.delay_standard_deviation_ms);
572 EXPECT_EQ(info.apm_statistics.echo_return_loss,
573 stats.apm_statistics.echo_return_loss);
574 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
575 stats.apm_statistics.echo_return_loss_enhancement);
576 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
577 stats.apm_statistics.residual_echo_likelihood);
578 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
579 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700580 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
581 stats.ana_statistics.bitrate_action_counter);
582 EXPECT_EQ(info.ana_statistics.channel_action_counter,
583 stats.ana_statistics.channel_action_counter);
584 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
585 stats.ana_statistics.dtx_action_counter);
586 EXPECT_EQ(info.ana_statistics.fec_action_counter,
587 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700588 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
589 stats.ana_statistics.frame_length_increase_counter);
590 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
591 stats.ana_statistics.frame_length_decrease_counter);
592 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
593 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800594 EXPECT_EQ(info.typing_noise_detected,
595 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700596 }
597
598 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
599 webrtc::AudioReceiveStream::Stats stats;
600 stats.remote_ssrc = 123;
601 stats.bytes_rcvd = 456;
602 stats.packets_rcvd = 768;
603 stats.packets_lost = 101;
604 stats.fraction_lost = 23.45f;
605 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100606 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700607 stats.ext_seqnum = 678;
608 stats.jitter_ms = 901;
609 stats.jitter_buffer_ms = 234;
610 stats.jitter_buffer_preferred_ms = 567;
611 stats.delay_estimate_ms = 890;
612 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700613 stats.total_samples_received = 5678901;
614 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200615 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200616 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700617 stats.expand_rate = 5.67f;
618 stats.speech_expand_rate = 8.90f;
619 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200620 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700621 stats.accelerate_rate = 4.56f;
622 stats.preemptive_expand_rate = 7.89f;
623 stats.decoding_calls_to_silence_generator = 12;
624 stats.decoding_calls_to_neteq = 345;
625 stats.decoding_normal = 67890;
626 stats.decoding_plc = 1234;
627 stats.decoding_cng = 5678;
628 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700629 stats.decoding_muted_output = 3456;
630 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200631 return stats;
632 }
633 void SetAudioReceiveStreamStats() {
634 for (auto* s : call_.GetAudioReceiveStreams()) {
635 s->SetStats(GetAudioReceiveStreamStats());
636 }
637 }
638 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700639 const auto stats = GetAudioReceiveStreamStats();
640 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
641 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
642 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
643 EXPECT_EQ(info.packets_lost, stats.packets_lost);
644 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
645 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800646 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
648 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
649 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200650 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700651 stats.jitter_buffer_preferred_ms);
652 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
653 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700654 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
655 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200656 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200657 EXPECT_EQ(info.jitter_buffer_delay_seconds,
658 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700659 EXPECT_EQ(info.expand_rate, stats.expand_rate);
660 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
661 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200662 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700663 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
664 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200665 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700666 stats.decoding_calls_to_silence_generator);
667 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
668 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
669 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
670 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
671 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700672 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200674 }
hbos1acfbd22016-11-17 23:43:29 -0800675 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
676 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
677 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
678 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
679 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
680 codec.ToCodecParameters());
681 }
682 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
683 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
684 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
685 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
686 codec.ToCodecParameters());
687 }
688 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200689
peah8271d042016-11-22 07:24:52 -0800690 bool IsHighPassFilterEnabled() {
691 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
692 }
693
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700695 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700696 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800697 webrtc::test::MockGainControl& apm_gc_;
698 webrtc::test::MockEchoCancellation& apm_ec_;
699 webrtc::test::MockNoiseSuppression& apm_ns_;
700 webrtc::test::MockVoiceDetection& apm_vd_;
skvlad11a9cbf2016-10-07 11:53:05 -0700701 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200702 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700703 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700704 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200705 cricket::AudioSendParameters send_parameters_;
706 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800707 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700708 webrtc::AudioProcessing::Config apm_config_;
709
stefanba4c0e42016-02-04 04:12:24 -0800710 private:
711 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712};
713
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714// Tests that we can create and destroy a channel.
715TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700716 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717}
718
solenberg31fec402016-05-06 02:13:12 -0700719// Test that we can add a send stream and that it has the correct defaults.
720TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
721 EXPECT_TRUE(SetupChannel());
722 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800723 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
724 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
725 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700726 EXPECT_EQ("", config.rtp.c_name);
727 EXPECT_EQ(0u, config.rtp.extensions.size());
728 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
729 config.send_transport);
730}
731
732// Test that we can add a receive stream and that it has the correct defaults.
733TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
734 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800735 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700736 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800737 GetRecvStreamConfig(kSsrcX);
738 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700739 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
740 EXPECT_FALSE(config.rtp.transport_cc);
741 EXPECT_EQ(0u, config.rtp.extensions.size());
742 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
743 config.rtcp_send_transport);
744 EXPECT_EQ("", config.sync_group);
745}
746
stefanba4c0e42016-02-04 04:12:24 -0800747TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700748 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800749 bool opus_found = false;
750 for (cricket::AudioCodec codec : codecs) {
751 if (codec.name == "opus") {
752 EXPECT_TRUE(HasTransportCc(codec));
753 opus_found = true;
754 }
755 }
756 EXPECT_TRUE(opus_found);
757}
758
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759// Test that we set our inbound codecs properly, including changing PT.
760TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700761 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200762 cricket::AudioRecvParameters parameters;
763 parameters.codecs.push_back(kIsacCodec);
764 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800765 parameters.codecs.push_back(kTelephoneEventCodec1);
766 parameters.codecs.push_back(kTelephoneEventCodec2);
767 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200768 parameters.codecs[2].id = 126;
769 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800770 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700771 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
772 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
773 {{0, {"PCMU", 8000, 1}},
774 {106, {"ISAC", 16000, 1}},
775 {126, {"telephone-event", 8000, 1}},
776 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777}
778
779// Test that we fail to set an unknown inbound codec.
780TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700781 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200782 cricket::AudioRecvParameters parameters;
783 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700784 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
788// Test that we fail if we have duplicate types in the inbound list.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
793 parameters.codecs.push_back(kCn16000Codec);
794 parameters.codecs[1].id = kIsacCodec.id;
795 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796}
797
798// Test that we can decode OPUS without stereo parameters.
799TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700800 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200801 cricket::AudioRecvParameters parameters;
802 parameters.codecs.push_back(kIsacCodec);
803 parameters.codecs.push_back(kPcmuCodec);
804 parameters.codecs.push_back(kOpusCodec);
805 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800806 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700807 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
808 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
809 {{0, {"PCMU", 8000, 1}},
810 {103, {"ISAC", 16000, 1}},
811 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that we can decode OPUS with stereo = 0.
815TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700816 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200817 cricket::AudioRecvParameters parameters;
818 parameters.codecs.push_back(kIsacCodec);
819 parameters.codecs.push_back(kPcmuCodec);
820 parameters.codecs.push_back(kOpusCodec);
821 parameters.codecs[2].params["stereo"] = "0";
822 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800823 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700824 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
825 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
826 {{0, {"PCMU", 8000, 1}},
827 {103, {"ISAC", 16000, 1}},
828 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829}
830
831// Test that we can decode OPUS with stereo = 1.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
837 parameters.codecs.push_back(kOpusCodec);
838 parameters.codecs[2].params["stereo"] = "1";
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700841 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
842 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
843 {{0, {"PCMU", 8000, 1}},
844 {103, {"ISAC", 16000, 1}},
845 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846}
847
848// Test that changes to recv codecs are applied to all streams.
849TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700850 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200851 cricket::AudioRecvParameters parameters;
852 parameters.codecs.push_back(kIsacCodec);
853 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800854 parameters.codecs.push_back(kTelephoneEventCodec1);
855 parameters.codecs.push_back(kTelephoneEventCodec2);
856 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 parameters.codecs[2].id = 126;
858 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700859 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
860 EXPECT_TRUE(AddRecvStream(ssrc));
861 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
862 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
863 {{0, {"PCMU", 8000, 1}},
864 {106, {"ISAC", 16000, 1}},
865 {126, {"telephone-event", 8000, 1}},
866 {107, {"telephone-event", 32000, 1}}})));
867 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868}
869
870TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700871 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200872 cricket::AudioRecvParameters parameters;
873 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800874 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876
solenberg2100c0b2017-03-01 11:29:29 -0800877 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800878 ASSERT_EQ(1, dm.count(106));
879 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882// Test that we can apply the same set of codecs again while playing.
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
887 parameters.codecs.push_back(kCn16000Codec);
888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700889 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891
deadbeefcb383672017-04-26 16:28:42 -0700892 // Remapping a payload type to a different codec should fail.
893 parameters.codecs[0] = kOpusCodec;
894 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200895 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800896 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897}
898
899// Test that we can add a codec while playing.
900TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700901 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 cricket::AudioRecvParameters parameters;
903 parameters.codecs.push_back(kIsacCodec);
904 parameters.codecs.push_back(kCn16000Codec);
905 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700906 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 parameters.codecs.push_back(kOpusCodec);
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911}
912
deadbeefcb383672017-04-26 16:28:42 -0700913// Test that we accept adding the same codec with a different payload type.
914// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
915TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
916 EXPECT_TRUE(SetupRecvStream());
917 cricket::AudioRecvParameters parameters;
918 parameters.codecs.push_back(kIsacCodec);
919 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
920
921 ++parameters.codecs[0].id;
922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
923}
924
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700926 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000928 // Test that when autobw is enabled, bitrate is kept as the default
929 // value. autobw is enabled for the following tests because the target
930 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931
932 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700933 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
935 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700936 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
ossu20a4b3f2017-04-27 02:08:52 -0700938 // opus, default bitrate == 32000 in mono.
939 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000942TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700943 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700946 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
947 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700948 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700951 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
952 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
953 // Rates above the max (510000) should be capped.
954 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955}
956
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000957TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700958 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000959
960 // Test that we can only set a maximum bitrate for a fixed-rate codec
961 // if it's bigger than the fixed rate.
962
963 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
965 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
966 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
967 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
968 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
969 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
970 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971}
972
973TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700974 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 const int kDesiredBitrate = 128000;
976 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700977 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700979 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000980
981 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800982 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000983
solenberg2100c0b2017-03-01 11:29:29 -0800984 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000985}
986
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987// Test that bitrate cannot be set for CBR codecs.
988// Bitrate is ignored if it is higher than the fixed bitrate.
989// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700991 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992
993 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700994 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800995 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200996
997 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700998 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800999 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001000
1001 send_parameters_.max_bandwidth_bps = 128;
1002 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001003 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004}
1005
skvlade0d46372016-04-07 22:59:22 -07001006// Test that the per-stream bitrate limit and the global
1007// bitrate limit both apply.
1008TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1009 EXPECT_TRUE(SetupSendStream());
1010
ossu20a4b3f2017-04-27 02:08:52 -07001011 // opus, default bitrate == 32000.
1012 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001013 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1014 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1015 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1016
1017 // CBR codecs allow both maximums to exceed the bitrate.
1018 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1019 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1020 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1021 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1022
1023 // CBR codecs don't allow per stream maximums to be too low.
1024 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1025 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1026}
1027
1028// Test that an attempt to set RtpParameters for a stream that does not exist
1029// fails.
1030TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1031 EXPECT_TRUE(SetupChannel());
1032 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001033 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001034 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1035
1036 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001037 EXPECT_FALSE(
1038 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001039}
1040
1041TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001042 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001043 // This test verifies that setting RtpParameters succeeds only if
1044 // the structure contains exactly one encoding.
1045 // TODO(skvlad): Update this test when we start supporting setting parameters
1046 // for each encoding individually.
1047
1048 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001049 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001050 // Two or more encodings should result in failure.
1051 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001052 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001053 // Zero encodings should also fail.
1054 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001055 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001056}
1057
1058// Changing the SSRC through RtpParameters is not allowed.
1059TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1060 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001061 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001062 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001064}
1065
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001066// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001067// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001068TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1069 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001070 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001072 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074 ASSERT_EQ(1u, parameters.encodings.size());
1075 ASSERT_TRUE(parameters.encodings[0].active);
1076 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001077 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079
1080 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001081 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001083 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001084 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086}
1087
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001088// Test that SetRtpSendParameters configures the correct encoding channel for
1089// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001090TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1091 SetupForMultiSendStream();
1092 // Create send streams.
1093 for (uint32_t ssrc : kSsrcs4) {
1094 EXPECT_TRUE(
1095 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1096 }
1097 // Configure one stream to be limited by the stream config, another to be
1098 // limited by the global max, and the third one with no per-stream limit
1099 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001100 SetGlobalMaxBitrate(kOpusCodec, 32000);
1101 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1102 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001103 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1104
ossu20a4b3f2017-04-27 02:08:52 -07001105 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1106 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1107 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001108
1109 // Remove the global cap; the streams should switch to their respective
1110 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001111 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001112 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1113 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1114 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001115}
1116
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001117// Test that GetRtpSendParameters returns the currently configured codecs.
1118TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001119 EXPECT_TRUE(SetupSendStream());
1120 cricket::AudioSendParameters parameters;
1121 parameters.codecs.push_back(kIsacCodec);
1122 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001123 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001124
solenberg2100c0b2017-03-01 11:29:29 -08001125 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001126 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1128 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129}
1130
deadbeefcb443432016-12-12 11:12:36 -08001131// Test that GetRtpSendParameters returns an SSRC.
1132TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1133 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001134 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001135 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001136 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001137}
1138
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001139// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001141 EXPECT_TRUE(SetupSendStream());
1142 cricket::AudioSendParameters parameters;
1143 parameters.codecs.push_back(kIsacCodec);
1144 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001145 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001146
solenberg2100c0b2017-03-01 11:29:29 -08001147 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148
1149 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001150 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001152 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001153 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1154 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155}
1156
minyuececec102017-03-27 13:04:25 -07001157// Test that max_bitrate_bps in send stream config gets updated correctly when
1158// SetRtpSendParameters is called.
1159TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1160 webrtc::test::ScopedFieldTrials override_field_trials(
1161 "WebRTC-Audio-SendSideBwe/Enabled/");
1162 EXPECT_TRUE(SetupSendStream());
1163 cricket::AudioSendParameters send_parameters;
1164 send_parameters.codecs.push_back(kOpusCodec);
1165 SetSendParameters(send_parameters);
1166
1167 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1168 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1169 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1170
1171 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001172 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001173 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001174
1175 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1176 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1177}
1178
Seth Hampson24722b32017-12-22 09:36:42 -08001179// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1180// a value <= 0, setting the parameters returns false.
1181TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1182 EXPECT_TRUE(SetupSendStream());
1183 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1184 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1185 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1186 rtp_parameters.encodings[0].bitrate_priority);
1187
1188 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001189 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001190 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001191 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001192}
1193
1194// Test that the bitrate_priority in the send stream config gets updated when
1195// SetRtpSendParameters is set for the VoiceMediaChannel.
1196TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1197 EXPECT_TRUE(SetupSendStream());
1198 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1199
1200 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1201 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1202 rtp_parameters.encodings[0].bitrate_priority);
1203 double new_bitrate_priority = 2.0;
1204 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001205 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001206
1207 // The priority should get set for both the audio channel's rtp parameters
1208 // and the audio send stream's audio config.
1209 EXPECT_EQ(
1210 new_bitrate_priority,
1211 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1212 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1213}
1214
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001215// Test that GetRtpReceiveParameters returns the currently configured codecs.
1216TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1217 EXPECT_TRUE(SetupRecvStream());
1218 cricket::AudioRecvParameters parameters;
1219 parameters.codecs.push_back(kIsacCodec);
1220 parameters.codecs.push_back(kPcmuCodec);
1221 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1222
1223 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001224 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1226 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1227 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1228}
1229
deadbeefcb443432016-12-12 11:12:36 -08001230// Test that GetRtpReceiveParameters returns an SSRC.
1231TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1232 EXPECT_TRUE(SetupRecvStream());
1233 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001234 channel_->GetRtpReceiveParameters(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 Brandstetterdb0cd9e2016-05-16 11:40:30 -07001239// Test that if we set/get parameters multiple times, we get the same results.
1240TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1241 EXPECT_TRUE(SetupRecvStream());
1242 cricket::AudioRecvParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
1245 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1246
1247 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001248 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001249
1250 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001251 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252
1253 // ... And this shouldn't change the params returned by
1254 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001255 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1256 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257}
1258
deadbeef3bc15102017-04-20 19:25:07 -07001259// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1260// aren't signaled. It should return an empty "RtpEncodingParameters" when
1261// configured to receive an unsignaled stream and no packets have been received
1262// yet, and start returning the SSRC once a packet has been received.
1263TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1264 ASSERT_TRUE(SetupChannel());
1265 // Call necessary methods to configure receiving a default stream as
1266 // soon as it arrives.
1267 cricket::AudioRecvParameters parameters;
1268 parameters.codecs.push_back(kIsacCodec);
1269 parameters.codecs.push_back(kPcmuCodec);
1270 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1271
1272 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1273 // stream. Should return nothing.
1274 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1275
1276 // Set a sink for an unsignaled stream.
1277 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1278 // Value of "0" means "unsignaled stream".
1279 channel_->SetRawAudioSink(0, std::move(fake_sink));
1280
1281 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1282 // in this method means "unsignaled stream".
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1284 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1285 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1286
1287 // Receive PCMU packet (SSRC=1).
1288 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1289
1290 // The |ssrc| member should still be unset.
1291 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1292 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1293 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1294}
1295
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001296// Test that we apply codecs properly.
1297TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001298 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001299 cricket::AudioSendParameters parameters;
1300 parameters.codecs.push_back(kIsacCodec);
1301 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001302 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001303 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001304 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001305 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001306 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1307 EXPECT_EQ(96, send_codec_spec.payload_type);
1308 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1309 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1310 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001311 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001312 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313}
1314
ossu20a4b3f2017-04-27 02:08:52 -07001315// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1316// AudioSendStream.
1317TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001318 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001319 cricket::AudioSendParameters parameters;
1320 parameters.codecs.push_back(kIsacCodec);
1321 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001322 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001323 parameters.codecs[0].id = 96;
1324 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001325 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001326 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001327 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001328 // Calling SetSendCodec again with same codec which is already set.
1329 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001330 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001331 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001332}
1333
ossu20a4b3f2017-04-27 02:08:52 -07001334// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1335// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001336
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001337// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].clockrate = 50000;
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001347// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
1353 parameters.codecs[0].channels = 0;
1354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001357// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].channels = 0;
1364 parameters.codecs[0].params["stereo"] = "1";
1365 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
1368// Test that if channel is 1 for opus and there's no stereo, we fail.
1369TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001370 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 cricket::AudioSendParameters parameters;
1372 parameters.codecs.push_back(kOpusCodec);
1373 parameters.codecs[0].bitrate = 0;
1374 parameters.codecs[0].channels = 1;
1375 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376}
1377
1378// Test that if channel is 1 for opus and stereo=0, we fail.
1379TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001380 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001381 cricket::AudioSendParameters parameters;
1382 parameters.codecs.push_back(kOpusCodec);
1383 parameters.codecs[0].bitrate = 0;
1384 parameters.codecs[0].channels = 1;
1385 parameters.codecs[0].params["stereo"] = "0";
1386 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387}
1388
1389// Test that if channel is 1 for opus and stereo=1, we fail.
1390TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001391 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 cricket::AudioSendParameters parameters;
1393 parameters.codecs.push_back(kOpusCodec);
1394 parameters.codecs[0].bitrate = 0;
1395 parameters.codecs[0].channels = 1;
1396 parameters.codecs[0].params["stereo"] = "1";
1397 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
ossu20a4b3f2017-04-27 02:08:52 -07001400// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001407 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408}
1409
ossu20a4b3f2017-04-27 02:08:52 -07001410// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001411TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001412 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 cricket::AudioSendParameters parameters;
1414 parameters.codecs.push_back(kOpusCodec);
1415 parameters.codecs[0].bitrate = 0;
1416 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001418 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419}
1420
ossu20a4b3f2017-04-27 02:08:52 -07001421// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001422TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001423 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 cricket::AudioSendParameters parameters;
1425 parameters.codecs.push_back(kOpusCodec);
1426 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001427 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001430 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001431
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001433 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001434 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001435}
1436
ossu20a4b3f2017-04-27 02:08:52 -07001437// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
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].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
ossu20a4b3f2017-04-27 02:08:52 -07001448// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001454 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001456 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001457 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001458
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001461 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001462}
1463
ossu20a4b3f2017-04-27 02:08:52 -07001464// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001466 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 cricket::AudioSendParameters parameters;
1468 parameters.codecs.push_back(kOpusCodec);
1469 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001470 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001471 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1472 EXPECT_EQ(111, spec.payload_type);
1473 EXPECT_EQ(96000, spec.target_bitrate_bps);
1474 EXPECT_EQ("opus", spec.format.name);
1475 EXPECT_EQ(2, spec.format.num_channels);
1476 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477}
1478
ossu20a4b3f2017-04-27 02:08:52 -07001479// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 30000;
1485 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001487 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
ossu20a4b3f2017-04-27 02:08:52 -07001490// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001492 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001493 cricket::AudioSendParameters parameters;
1494 parameters.codecs.push_back(kOpusCodec);
1495 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001497 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498}
1499
ossu20a4b3f2017-04-27 02:08:52 -07001500// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
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 = 30000;
1506 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001509}
1510
stefan13f1a0a2016-11-30 07:22:58 -08001511TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1512 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1513 200000);
1514}
1515
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1517 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1518}
1519
1520TEST_F(WebRtcVoiceEngineTestFake,
1521 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1522 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1523}
1524
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1526 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1527}
1528
1529TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001530 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001531 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1532 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001533 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001534 SetSendParameters(send_parameters_);
1535 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1536 << "Setting max bitrate should keep previous min bitrate.";
1537 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1538 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001539 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001540}
1541
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001542// Test that we can enable NACK with opus as caller.
1543TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001544 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 cricket::AudioSendParameters parameters;
1546 parameters.codecs.push_back(kOpusCodec);
1547 parameters.codecs[0].AddFeedbackParam(
1548 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1549 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001550 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001551 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553}
1554
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001555// Test that we can enable NACK with opus as callee.
1556TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001557 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 cricket::AudioSendParameters parameters;
1559 parameters.codecs.push_back(kOpusCodec);
1560 parameters.codecs[0].AddFeedbackParam(
1561 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1562 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001563 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001564 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001565 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001566 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001567
1568 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001569 cricket::StreamParams::CreateLegacy(kSsrcX)));
1570 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001571}
1572
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573// Test that we can enable NACK on receive streams.
1574TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001575 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001576 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 cricket::AudioSendParameters parameters;
1578 parameters.codecs.push_back(kOpusCodec);
1579 parameters.codecs[0].AddFeedbackParam(
1580 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1581 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1583 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001584 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1586 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587}
1588
1589// Test that we can disable NACK.
1590TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001591 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001592 cricket::AudioSendParameters parameters;
1593 parameters.codecs.push_back(kOpusCodec);
1594 parameters.codecs[0].AddFeedbackParam(
1595 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1596 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001597 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 parameters.codecs.clear();
1601 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001603 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
1606// Test that we can disable NACK on receive streams.
1607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001610 cricket::AudioSendParameters parameters;
1611 parameters.codecs.push_back(kOpusCodec);
1612 parameters.codecs[0].AddFeedbackParam(
1613 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1614 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1617 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 parameters.codecs.clear();
1620 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1623 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624}
1625
1626// Test that NACK is enabled on a new receive stream.
1627TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001628 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 cricket::AudioSendParameters parameters;
1630 parameters.codecs.push_back(kIsacCodec);
1631 parameters.codecs.push_back(kCn16000Codec);
1632 parameters.codecs[0].AddFeedbackParam(
1633 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1634 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
solenberg2100c0b2017-03-01 11:29:29 -08001638 EXPECT_TRUE(AddRecvStream(kSsrcY));
1639 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1640 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1641 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642}
1643
stefanba4c0e42016-02-04 04:12:24 -08001644TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001646 cricket::AudioSendParameters send_parameters;
1647 send_parameters.codecs.push_back(kOpusCodec);
1648 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001649 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001650
1651 cricket::AudioRecvParameters recv_parameters;
1652 recv_parameters.codecs.push_back(kIsacCodec);
1653 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_TRUE(AddRecvStream(kSsrcX));
1655 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001656 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001657 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001658
ossudedfd282016-06-14 07:12:39 -07001659 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001662 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001663 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001664}
1665
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001666// Test that we can switch back and forth between Opus and ISAC with CN.
1667TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001668 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001669
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001670 cricket::AudioSendParameters opus_parameters;
1671 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(111, spec.payload_type);
1676 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001677 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters isac_parameters;
1680 isac_parameters.codecs.push_back(kIsacCodec);
1681 isac_parameters.codecs.push_back(kCn16000Codec);
1682 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001684 {
ossu20a4b3f2017-04-27 02:08:52 -07001685 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1686 EXPECT_EQ(103, spec.payload_type);
1687 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001688 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001691 {
ossu20a4b3f2017-04-27 02:08:52 -07001692 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1693 EXPECT_EQ(111, spec.payload_type);
1694 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001695 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696}
1697
1698// Test that we handle various ways of specifying bitrate.
1699TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001700 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001701 cricket::AudioSendParameters parameters;
1702 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001704 {
ossu20a4b3f2017-04-27 02:08:52 -07001705 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1706 EXPECT_EQ(103, spec.payload_type);
1707 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1708 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001710
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001713 {
ossu20a4b3f2017-04-27 02:08:52 -07001714 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1715 EXPECT_EQ(103, spec.payload_type);
1716 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1717 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001718 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001719 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001720 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001721 {
ossu20a4b3f2017-04-27 02:08:52 -07001722 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1723 EXPECT_EQ(103, spec.payload_type);
1724 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1725 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001726 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001728 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001730 {
ossu20a4b3f2017-04-27 02:08:52 -07001731 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1732 EXPECT_EQ(0, spec.payload_type);
1733 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1734 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001735 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001739 {
ossu20a4b3f2017-04-27 02:08:52 -07001740 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1741 EXPECT_EQ(0, spec.payload_type);
1742 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1743 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001744 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001746 parameters.codecs[0] = kOpusCodec;
1747 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001749 {
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(111, spec.payload_type);
1752 EXPECT_STREQ("opus", spec.format.name.c_str());
1753 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755}
1756
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001757// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001759 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 cricket::AudioSendParameters parameters;
1761 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001762}
1763
1764// Test that we can set send codecs even with telephone-event codec as the first
1765// one on the list.
1766TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001769 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001770 parameters.codecs.push_back(kIsacCodec);
1771 parameters.codecs.push_back(kPcmuCodec);
1772 parameters.codecs[0].id = 98; // DTMF
1773 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001774 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001775 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1776 EXPECT_EQ(96, spec.payload_type);
1777 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001778 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001779}
1780
solenberg31642aa2016-03-14 08:00:37 -07001781// Test that payload type range is limited for telephone-event codec.
1782TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001783 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001784 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001785 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001786 parameters.codecs.push_back(kIsacCodec);
1787 parameters.codecs[0].id = 0; // DTMF
1788 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001790 EXPECT_TRUE(channel_->CanInsertDtmf());
1791 parameters.codecs[0].id = 128; // DTMF
1792 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1793 EXPECT_FALSE(channel_->CanInsertDtmf());
1794 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001795 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001796 EXPECT_TRUE(channel_->CanInsertDtmf());
1797 parameters.codecs[0].id = -1; // DTMF
1798 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1799 EXPECT_FALSE(channel_->CanInsertDtmf());
1800}
1801
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001802// Test that we can set send codecs even with CN codec as the first
1803// one on the list.
1804TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001805 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001806 cricket::AudioSendParameters parameters;
1807 parameters.codecs.push_back(kCn16000Codec);
1808 parameters.codecs.push_back(kIsacCodec);
1809 parameters.codecs.push_back(kPcmuCodec);
1810 parameters.codecs[0].id = 98; // wideband CN
1811 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001812 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001813 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1814 EXPECT_EQ(96, send_codec_spec.payload_type);
1815 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001816 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817}
1818
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001819// Test that we set VAD and DTMF types correctly as caller.
1820TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001821 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 cricket::AudioSendParameters parameters;
1823 parameters.codecs.push_back(kIsacCodec);
1824 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs.push_back(kCn16000Codec);
1827 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001828 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 parameters.codecs[0].id = 96;
1830 parameters.codecs[2].id = 97; // wideband CN
1831 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001832 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001833 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1834 EXPECT_EQ(96, send_codec_spec.payload_type);
1835 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1836 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001837 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001838 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001839}
1840
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001841// Test that we set VAD and DTMF types correctly as callee.
1842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 cricket::AudioSendParameters parameters;
1845 parameters.codecs.push_back(kIsacCodec);
1846 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001847 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 parameters.codecs.push_back(kCn16000Codec);
1849 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001850 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001851 parameters.codecs[0].id = 96;
1852 parameters.codecs[2].id = 97; // wideband CN
1853 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001854 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001855 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001856 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001857
ossu20a4b3f2017-04-27 02:08:52 -07001858 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1859 EXPECT_EQ(96, send_codec_spec.payload_type);
1860 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1861 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001862 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001863 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001864}
1865
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001866// Test that we only apply VAD if we have a CN codec that matches the
1867// send codec clockrate.
1868TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001871 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001872 parameters.codecs.push_back(kIsacCodec);
1873 parameters.codecs.push_back(kCn16000Codec);
1874 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001875 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001876 {
ossu20a4b3f2017-04-27 02:08:52 -07001877 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1878 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1879 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001880 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001881 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001883 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001884 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001885 {
ossu20a4b3f2017-04-27 02:08:52 -07001886 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1887 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001888 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001889 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001893 {
ossu20a4b3f2017-04-27 02:08:52 -07001894 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1895 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1896 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001898 }
Brave Yao5225dd82015-03-26 07:39:19 +08001899 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001901 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001902 {
ossu20a4b3f2017-04-27 02:08:52 -07001903 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1904 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001905 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001906 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907}
1908
1909// Test that we perform case-insensitive matching of codec names.
1910TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001911 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001912 cricket::AudioSendParameters parameters;
1913 parameters.codecs.push_back(kIsacCodec);
1914 parameters.codecs.push_back(kPcmuCodec);
1915 parameters.codecs.push_back(kCn16000Codec);
1916 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001917 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001918 parameters.codecs[0].name = "iSaC";
1919 parameters.codecs[0].id = 96;
1920 parameters.codecs[2].id = 97; // wideband CN
1921 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001922 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001923 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1924 EXPECT_EQ(96, send_codec_spec.payload_type);
1925 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1926 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001927 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001928 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929}
1930
stefanba4c0e42016-02-04 04:12:24 -08001931class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1932 public:
1933 WebRtcVoiceEngineWithSendSideBweTest()
1934 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1935};
1936
1937TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1938 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001939 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001940 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001941 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1942 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1943 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001944 extension.id);
1945 return;
1946 }
1947 }
1948 FAIL() << "Transport sequence number extension not in header-extension list.";
1949}
1950
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001951// Test support for audio level header extension.
1952TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001953 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001954}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001955TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001956 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001957}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001958
solenbergd4adce42016-11-17 06:26:52 -08001959// Test support for transport sequence number header extension.
1960TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1961 TestSetSendRtpHeaderExtensions(
1962 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001963}
solenbergd4adce42016-11-17 06:26:52 -08001964TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1965 TestSetRecvRtpHeaderExtensions(
1966 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967}
1968
solenberg1ac56142015-10-13 03:58:19 -07001969// Test that we can create a channel and start sending on it.
1970TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(send_parameters_);
1973 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001974 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001975 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001977}
1978
1979// Test that a channel will send if and only if it has a source and is enabled
1980// for sending.
1981TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001982 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001984 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001985 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1987 SetAudioSend(kSsrcX, true, &fake_source_);
1988 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1989 SetAudioSend(kSsrcX, true, nullptr);
1990 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001991}
1992
solenberg94218532016-06-16 10:53:22 -07001993// Test that a channel is muted/unmuted.
1994TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1995 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001996 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1998 SetAudioSend(kSsrcX, true, nullptr);
1999 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2000 SetAudioSend(kSsrcX, false, nullptr);
2001 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002002}
2003
solenberg6d6e7c52016-04-13 09:07:30 -07002004// Test that SetSendParameters() does not alter a stream's send state.
2005TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2006 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002007 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002008
2009 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002010 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002011 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002012
2013 // Changing RTP header extensions will recreate the AudioSendStream.
2014 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002015 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002017 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002018
2019 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002020 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002021 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002022
2023 // Changing RTP header extensions will recreate the AudioSendStream.
2024 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002025 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002026 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002027}
2028
solenberg1ac56142015-10-13 03:58:19 -07002029// Test that we can create a channel and start playing out on it.
2030TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002031 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002032 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002033 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002034 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002035 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002036 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002037}
2038
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039// Test that we can add and remove send streams.
2040TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2041 SetupForMultiSendStream();
2042
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002044 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045
solenbergc96df772015-10-21 13:01:53 -07002046 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002047 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002048 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002049 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002051 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 }
tfarina5237aaf2015-11-10 23:44:30 -08002053 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054
solenbergc96df772015-10-21 13:01:53 -07002055 // Delete the send streams.
2056 for (uint32_t ssrc : kSsrcs4) {
2057 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002058 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002059 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 }
solenbergc96df772015-10-21 13:01:53 -07002061 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062}
2063
2064// Test SetSendCodecs correctly configure the codecs in all send streams.
2065TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2066 SetupForMultiSendStream();
2067
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002069 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002071 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002072 }
2073
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002074 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002076 parameters.codecs.push_back(kIsacCodec);
2077 parameters.codecs.push_back(kCn16000Codec);
2078 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002079 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080
2081 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002082 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002083 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2084 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002085 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2086 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2087 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002088 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
2090
minyue7a973442016-10-20 03:27:12 -07002091 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002092 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002093 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002094 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002095 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2096 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002097 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2098 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002099 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002100 }
2101}
2102
2103// Test we can SetSend on all send streams correctly.
2104TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2105 SetupForMultiSendStream();
2106
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002107 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002108 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002110 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002111 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002112 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 }
2114
2115 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002116 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002117 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002119 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120 }
2121
2122 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002123 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002124 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002126 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127 }
2128}
2129
2130// Test we can set the correct statistics on all send streams.
2131TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2132 SetupForMultiSendStream();
2133
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002135 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002137 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 }
solenberg85a04962015-10-27 03:35:21 -07002139
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002140 // Create a receive stream to check that none of the send streams end up in
2141 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002142 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002143
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002144 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002145 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002146 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002147 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148
solenberg85a04962015-10-27 03:35:21 -07002149 // Check stats for the added streams.
2150 {
2151 cricket::VoiceMediaInfo info;
2152 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153
solenberg85a04962015-10-27 03:35:21 -07002154 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002155 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002156 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002157 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002158 }
hbos1acfbd22016-11-17 23:43:29 -08002159 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002160
2161 // We have added one receive stream. We should see empty stats.
2162 EXPECT_EQ(info.receivers.size(), 1u);
2163 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164 }
solenberg1ac56142015-10-13 03:58:19 -07002165
solenberg2100c0b2017-03-01 11:29:29 -08002166 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002167 {
2168 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002169 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002170 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002171 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002172 EXPECT_EQ(0u, info.receivers.size());
2173 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002174
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002175 // Deliver a new packet - a default receive stream should be created and we
2176 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002177 {
2178 cricket::VoiceMediaInfo info;
2179 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2180 SetAudioReceiveStreamStats();
2181 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002182 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002183 EXPECT_EQ(1u, info.receivers.size());
2184 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002185 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002186 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002187}
2188
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002189// Test that we can add and remove receive streams, and do proper send/playout.
2190// We can receive on multiple streams while sending one stream.
2191TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002192 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
solenberg1ac56142015-10-13 03:58:19 -07002194 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002195 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002196 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002197
solenberg1ac56142015-10-13 03:58:19 -07002198 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002199 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002200 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202
solenberg1ac56142015-10-13 03:58:19 -07002203 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002204 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002205
2206 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002207 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2208 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2209 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002210
2211 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002212 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002213 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002214
2215 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002216 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002217 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2218 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002219
aleloi84ef6152016-08-04 05:28:21 -07002220 // Restart playout and make sure recv streams are played out.
2221 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002222 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2223 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002224
aleloi84ef6152016-08-04 05:28:21 -07002225 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002226 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2227 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002228}
2229
wu@webrtc.org97077a32013-10-25 21:18:33 +00002230TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002231 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002232 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2233 .Times(1)
2234 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002235 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2236 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002237 send_parameters_.options.tx_agc_target_dbov = 3;
2238 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2239 send_parameters_.options.tx_agc_limiter = true;
2240 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002241 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2242 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2243 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002244 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002245}
2246
minyue6b825df2016-10-31 04:08:32 -07002247TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2248 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002249 send_parameters_.options.audio_network_adaptor = true;
2250 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002251 SetSendParameters(send_parameters_);
2252 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002253 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002254}
2255
2256TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2257 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002258 send_parameters_.options.audio_network_adaptor = true;
2259 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002260 SetSendParameters(send_parameters_);
2261 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002262 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002263 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002264 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002265 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002266 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002267}
2268
2269TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2270 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002271 send_parameters_.options.audio_network_adaptor = true;
2272 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002273 SetSendParameters(send_parameters_);
2274 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002275 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002276 const int initial_num = call_.GetNumCreatedSendStreams();
2277 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002278 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002279 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2280 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002281 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002282 // AudioSendStream not expected to be recreated.
2283 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2284 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002285 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002286}
2287
michaelt6672b262017-01-11 10:17:59 -08002288class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2289 : public WebRtcVoiceEngineTestFake {
2290 public:
2291 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2292 : WebRtcVoiceEngineTestFake(
2293 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2294 "Enabled/") {}
2295};
2296
2297TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2298 EXPECT_TRUE(SetupSendStream());
2299 cricket::AudioSendParameters parameters;
2300 parameters.codecs.push_back(kOpusCodec);
2301 SetSendParameters(parameters);
2302 const int initial_num = call_.GetNumCreatedSendStreams();
2303 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2304
2305 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2306 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002307 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2308 constexpr int kMinOverheadBps =
2309 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002310
2311 constexpr int kOpusMinBitrateBps = 6000;
2312 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002313 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002314 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002315 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002316 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002317
Oskar Sundbom78807582017-11-16 11:09:55 +01002318 parameters.options.audio_network_adaptor = true;
2319 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002320 SetSendParameters(parameters);
2321
ossu11bfc532017-02-16 05:37:06 -08002322 constexpr int kMinOverheadWithAnaBps =
2323 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002324
2325 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002326 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002327
minyuececec102017-03-27 13:04:25 -07002328 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002329 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002330}
2331
minyuececec102017-03-27 13:04:25 -07002332// This test is similar to
2333// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2334// additional field trial.
2335TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2336 SetRtpSendParameterUpdatesMaxBitrate) {
2337 EXPECT_TRUE(SetupSendStream());
2338 cricket::AudioSendParameters send_parameters;
2339 send_parameters.codecs.push_back(kOpusCodec);
2340 SetSendParameters(send_parameters);
2341
2342 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2343 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2344 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2345
2346 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002347 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002348 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002349
2350 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2351#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2352 constexpr int kMinOverhead = 3333;
2353#else
2354 constexpr int kMinOverhead = 6666;
2355#endif
2356 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2357}
2358
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002359// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002360// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002362 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002363 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002364}
2365
2366TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2367 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002368 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002369 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002370 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002371 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002372 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002373 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002374 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002375
solenberg85a04962015-10-27 03:35:21 -07002376 // Check stats for the added streams.
2377 {
2378 cricket::VoiceMediaInfo info;
2379 EXPECT_EQ(true, channel_->GetStats(&info));
2380
2381 // We have added one send stream. We should see the stats we've set.
2382 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002383 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002384 // We have added one receive stream. We should see empty stats.
2385 EXPECT_EQ(info.receivers.size(), 1u);
2386 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2387 }
solenberg1ac56142015-10-13 03:58:19 -07002388
solenberg566ef242015-11-06 15:34:49 -08002389 // Start sending - this affects some reported stats.
2390 {
2391 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002392 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002393 EXPECT_EQ(true, channel_->GetStats(&info));
2394 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002395 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002396 }
2397
solenberg2100c0b2017-03-01 11:29:29 -08002398 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002399 {
2400 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002401 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002402 EXPECT_EQ(true, channel_->GetStats(&info));
2403 EXPECT_EQ(1u, info.senders.size());
2404 EXPECT_EQ(0u, info.receivers.size());
2405 }
solenberg1ac56142015-10-13 03:58:19 -07002406
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002407 // Deliver a new packet - a default receive stream should be created and we
2408 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002409 {
2410 cricket::VoiceMediaInfo info;
2411 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2412 SetAudioReceiveStreamStats();
2413 EXPECT_EQ(true, channel_->GetStats(&info));
2414 EXPECT_EQ(1u, info.senders.size());
2415 EXPECT_EQ(1u, info.receivers.size());
2416 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002417 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002418 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419}
2420
2421// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002422// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002424 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002425 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2426 EXPECT_TRUE(AddRecvStream(kSsrcY));
2427 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428}
2429
2430// Test that the local SSRC is the same on sending and receiving channels if the
2431// receive channel is created before the send channel.
2432TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002433 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002434 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002436 cricket::StreamParams::CreateLegacy(kSsrcX)));
2437 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2438 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439}
2440
2441// Test that we can properly receive packets.
2442TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002443 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002444 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002446
2447 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2448 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449}
2450
2451// Test that we can properly receive packets on multiple streams.
2452TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002453 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002454 const uint32_t ssrc1 = 1;
2455 const uint32_t ssrc2 = 2;
2456 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002457 EXPECT_TRUE(AddRecvStream(ssrc1));
2458 EXPECT_TRUE(AddRecvStream(ssrc2));
2459 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002461 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002462 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002464 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465 }
mflodman3d7db262016-04-29 00:57:13 -07002466
2467 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2468 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2469 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2470
2471 EXPECT_EQ(s1.received_packets(), 0);
2472 EXPECT_EQ(s2.received_packets(), 0);
2473 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002474
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002476 EXPECT_EQ(s1.received_packets(), 0);
2477 EXPECT_EQ(s2.received_packets(), 0);
2478 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002479
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002481 EXPECT_EQ(s1.received_packets(), 1);
2482 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2483 EXPECT_EQ(s2.received_packets(), 0);
2484 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002485
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_EQ(s1.received_packets(), 1);
2488 EXPECT_EQ(s2.received_packets(), 1);
2489 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2490 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002491
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002493 EXPECT_EQ(s1.received_packets(), 1);
2494 EXPECT_EQ(s2.received_packets(), 1);
2495 EXPECT_EQ(s3.received_packets(), 1);
2496 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002497
mflodman3d7db262016-04-29 00:57:13 -07002498 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2499 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2500 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501}
2502
solenberg2100c0b2017-03-01 11:29:29 -08002503// Test that receiving on an unsignaled stream works (a stream is created).
2504TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002505 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002506 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2507
solenberg7e63ef02015-11-20 00:19:43 -08002508 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002509
2510 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002511 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2512 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002513}
2514
solenberg2100c0b2017-03-01 11:29:29 -08002515// Test that receiving N unsignaled stream works (streams will be created), and
2516// that packets are forwarded to them all.
2517TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002518 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002519 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002520 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2521
solenberg2100c0b2017-03-01 11:29:29 -08002522 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002523 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002524 rtc::SetBE32(&packet[8], ssrc);
2525 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002526
solenberg2100c0b2017-03-01 11:29:29 -08002527 // Verify we have one new stream for each loop iteration.
2528 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002529 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2530 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002531 }
mflodman3d7db262016-04-29 00:57:13 -07002532
solenberg2100c0b2017-03-01 11:29:29 -08002533 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002534 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002535 rtc::SetBE32(&packet[8], ssrc);
2536 DeliverPacket(packet, sizeof(packet));
2537
solenbergebb349d2017-03-13 05:46:15 -07002538 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002539 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2540 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2541 }
2542
2543 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2544 constexpr uint32_t kAnotherSsrc = 667;
2545 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002546 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002547
2548 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002549 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002550 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002551 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002552 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2553 EXPECT_EQ(2, streams[i]->received_packets());
2554 }
2555 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2556 EXPECT_EQ(1, streams[i]->received_packets());
2557 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002558 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002559}
2560
solenberg2100c0b2017-03-01 11:29:29 -08002561// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002562// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002563TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002564 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002565 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002566 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2567
2568 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002569 const uint32_t signaled_ssrc = 1;
2570 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002571 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002572 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002573 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2574 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002575 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002576
2577 // Note that the first unknown SSRC cannot be 0, because we only support
2578 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002579 const uint32_t unsignaled_ssrc = 7011;
2580 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002581 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002582 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2583 packet, sizeof(packet)));
2584 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2585
2586 DeliverPacket(packet, sizeof(packet));
2587 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2588
2589 rtc::SetBE32(&packet[8], signaled_ssrc);
2590 DeliverPacket(packet, sizeof(packet));
2591 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2592 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002593}
2594
solenberg4904fb62017-02-17 12:01:14 -08002595// Two tests to verify that adding a receive stream with the same SSRC as a
2596// previously added unsignaled stream will only recreate underlying stream
2597// objects if the stream parameters have changed.
2598TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2599 EXPECT_TRUE(SetupChannel());
2600
2601 // Spawn unsignaled stream with SSRC=1.
2602 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2603 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2604 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2605 sizeof(kPcmuFrame)));
2606
2607 // Verify that the underlying stream object in Call is not recreated when a
2608 // stream with SSRC=1 is added.
2609 const auto& streams = call_.GetAudioReceiveStreams();
2610 EXPECT_EQ(1, streams.size());
2611 int audio_receive_stream_id = streams.front()->id();
2612 EXPECT_TRUE(AddRecvStream(1));
2613 EXPECT_EQ(1, streams.size());
2614 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2615}
2616
2617TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2618 EXPECT_TRUE(SetupChannel());
2619
2620 // Spawn unsignaled stream with SSRC=1.
2621 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2622 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2623 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2624 sizeof(kPcmuFrame)));
2625
2626 // Verify that the underlying stream object in Call *is* recreated when a
2627 // stream with SSRC=1 is added, and which has changed stream parameters.
2628 const auto& streams = call_.GetAudioReceiveStreams();
2629 EXPECT_EQ(1, streams.size());
2630 int audio_receive_stream_id = streams.front()->id();
2631 cricket::StreamParams stream_params;
2632 stream_params.ssrcs.push_back(1);
2633 stream_params.sync_label = "sync_label";
2634 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2635 EXPECT_EQ(1, streams.size());
2636 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2637}
2638
solenberg1ac56142015-10-13 03:58:19 -07002639// Test that AddRecvStream creates new stream.
2640TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002641 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002642 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002643}
2644
2645// Test that after adding a recv stream, we do not decode more codecs than
2646// those previously passed into SetRecvCodecs.
2647TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002648 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002649 cricket::AudioRecvParameters parameters;
2650 parameters.codecs.push_back(kIsacCodec);
2651 parameters.codecs.push_back(kPcmuCodec);
2652 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002653 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002654 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2655 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2656 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002657}
2658
2659// Test that we properly clean up any streams that were added, even if
2660// not explicitly removed.
2661TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002662 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002663 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002664 EXPECT_TRUE(AddRecvStream(1));
2665 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002666
2667 EXPECT_EQ(1, call_.GetAudioSendStreams().size());
2668 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669 delete channel_;
2670 channel_ = NULL;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002671 EXPECT_EQ(0, call_.GetAudioSendStreams().size());
2672 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002673}
2674
wu@webrtc.org78187522013-10-07 23:32:02 +00002675TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002676 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002677 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002678}
2679
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002680TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002681 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002682 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002683 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002684}
2685
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002686// Test the InsertDtmf on default send stream as caller.
2687TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002688 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002689}
2690
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002691// Test the InsertDtmf on default send stream as callee
2692TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002693 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002694}
2695
2696// Test the InsertDtmf on specified send stream as caller.
2697TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002698 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002699}
2700
2701// Test the InsertDtmf on specified send stream as callee.
2702TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002703 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704}
2705
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002706TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002707 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002708 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002709 EXPECT_CALL(adm_,
2710 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2711 EXPECT_CALL(adm_,
2712 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2713 EXPECT_CALL(adm_,
2714 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002715
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002716 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2717 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718
solenberg246b8172015-12-08 09:50:23 -08002719 // Nothing set in AudioOptions, so everything should be as default.
2720 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002721 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002722 EXPECT_TRUE(IsHighPassFilterEnabled());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002723 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2724 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725
2726 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002727 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2728 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002729 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002730 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731
2732 // Turn echo cancellation back on, with settings, and make sure
2733 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002734 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2735 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002736 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002737 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002739 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2740 // control.
solenberg76377c52017-02-21 00:54:31 -08002741 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002743 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002744 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002745
2746 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002747 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2748 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002749 send_parameters_.options.delay_agnostic_aec = false;
2750 send_parameters_.options.extended_filter_aec = false;
2751 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002753
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002754 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002759
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002761 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002763 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002764 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002765 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002766 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767
2768 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002771 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002772 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002773 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002776 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002777 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002779 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002780 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002781 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002782 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2783 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002784 send_parameters_.options.noise_suppression = false;
2785 send_parameters_.options.highpass_filter = false;
2786 send_parameters_.options.typing_detection = false;
2787 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002788 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002789 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002790
solenberg1ac56142015-10-13 03:58:19 -07002791 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002792 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002794 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002795 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002796 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002797 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002799 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800}
2801
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002803 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002804 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002805 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002806 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002807 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002808 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002809 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002810 EXPECT_CALL(adm_,
2811 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2812 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2813 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002814 webrtc::AudioProcessing::Config apm_config;
2815 EXPECT_CALL(*apm_, GetConfig())
2816 .Times(10)
2817 .WillRepeatedly(ReturnPointee(&apm_config));
2818 EXPECT_CALL(*apm_, ApplyConfig(_))
2819 .Times(10)
2820 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002821 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002822
kwiberg686a8ef2016-02-26 03:00:35 -08002823 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002824 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002825 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002826 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002827 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002828 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002829
2830 // Have to add a stream to make SetSend work.
2831 cricket::StreamParams stream1;
2832 stream1.ssrcs.push_back(1);
2833 channel1->AddSendStream(stream1);
2834 cricket::StreamParams stream2;
2835 stream2.ssrcs.push_back(2);
2836 channel2->AddSendStream(stream2);
2837
2838 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002839 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002840 parameters_options_all.options.echo_cancellation = true;
2841 parameters_options_all.options.auto_gain_control = true;
2842 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002843 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2844 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002845 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002846 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002847 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002848 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002849 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002850 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002851 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002852 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002855 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002856 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002857 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2858 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002859 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002860 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002861 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002862 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002863 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002864 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 expected_options.echo_cancellation = true;
2866 expected_options.auto_gain_control = true;
2867 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002868 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869
2870 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002872 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002875 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002876 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002877 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002878 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002879 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002880 expected_options.echo_cancellation = true;
2881 expected_options.auto_gain_control = false;
2882 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002883 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002889 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002891 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892
solenberg76377c52017-02-21 00:54:31 -08002893 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002895 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002896 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002897 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002898 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002899 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002903 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002905 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002907 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002909 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002910 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2911 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002912 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2913 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002916 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002917 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002920 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002921 expected_options.echo_cancellation = true;
2922 expected_options.auto_gain_control = false;
2923 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002924 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925}
2926
wu@webrtc.orgde305012013-10-31 15:40:38 +00002927// This test verifies DSCP settings are properly applied on voice media channel.
2928TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002929 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002930 cricket::FakeNetworkInterface network_interface;
2931 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002932 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002933
peahb1c9d1d2017-07-25 15:45:24 -07002934 webrtc::AudioProcessing::Config apm_config;
2935 EXPECT_CALL(*apm_, GetConfig())
2936 .Times(3)
2937 .WillRepeatedly(ReturnPointee(&apm_config));
2938 EXPECT_CALL(*apm_, ApplyConfig(_))
2939 .Times(3)
2940 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002941 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002942
solenbergbc37fc82016-04-04 09:54:44 -07002943 channel.reset(
2944 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002945 channel->SetInterface(&network_interface);
2946 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2947 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2948
2949 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002950 channel.reset(
2951 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002952 channel->SetInterface(&network_interface);
2953 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2954
2955 // Verify that setting the option to false resets the
2956 // DiffServCodePoint.
2957 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002958 channel.reset(
2959 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002960 channel->SetInterface(&network_interface);
2961 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2962 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2963
2964 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002965}
2966
solenberg4bac9c52015-10-09 02:32:53 -07002967TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002968 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002969 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002970 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002971 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002973 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2974 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2975 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002976}
2977
solenberg2100c0b2017-03-01 11:29:29 -08002978TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002979 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002980
2981 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002982 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002983 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2984
2985 // Should remember the volume "2" which will be set on new unsignaled streams,
2986 // and also set the gain to 2 on existing unsignaled streams.
2987 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2988 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2989
2990 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2991 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2992 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2993 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2994 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2995 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2996
2997 // Setting gain with SSRC=0 should affect all unsignaled streams.
2998 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002999 if (kMaxUnsignaledRecvStreams > 1) {
3000 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3001 }
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3003
3004 // Setting gain on an individual stream affects only that.
3005 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003006 if (kMaxUnsignaledRecvStreams > 1) {
3007 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3008 }
solenberg2100c0b2017-03-01 11:29:29 -08003009 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010}
3011
pbos8fc7fa72015-07-15 08:02:58 -07003012TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003013 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003014 const std::string kSyncLabel = "AvSyncLabel";
3015
solenbergff976312016-03-30 23:28:51 -07003016 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003017 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3018 sp.sync_label = kSyncLabel;
3019 // Creating two channels to make sure that sync label is set properly for both
3020 // the default voice channel and following ones.
3021 EXPECT_TRUE(channel_->AddRecvStream(sp));
3022 sp.ssrcs[0] += 1;
3023 EXPECT_TRUE(channel_->AddRecvStream(sp));
3024
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003025 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003026 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003027 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003028 << "SyncGroup should be set based on sync_label";
3029 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003030 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003031 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003032}
3033
solenberg3a941542015-11-16 07:34:50 -08003034// TODO(solenberg): Remove, once recv streams are configured through Call.
3035// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003036TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003037 // Test that setting the header extensions results in the expected state
3038 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003039 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003040 ssrcs.push_back(223);
3041 ssrcs.push_back(224);
3042
solenbergff976312016-03-30 23:28:51 -07003043 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003044 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003045 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003046 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003047 cricket::StreamParams::CreateLegacy(ssrc)));
3048 }
3049
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003050 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003051 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003052 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003053 EXPECT_NE(nullptr, s);
3054 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3055 }
3056
3057 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003058 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003059 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003060 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003061 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003062 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003063 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003064 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003065 EXPECT_NE(nullptr, s);
3066 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003067 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3068 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003069 for (const auto& s_ext : s_exts) {
3070 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003071 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003072 }
3073 }
3074 }
3075 }
3076
3077 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003078 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003079 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003080 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003081 EXPECT_NE(nullptr, s);
3082 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3083 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003084}
3085
3086TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3087 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003088 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003089 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003090 static const unsigned char kRtcp[] = {
3091 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3092 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3095 };
jbaucheec21bd2016-03-20 06:15:43 -07003096 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097
solenbergff976312016-03-30 23:28:51 -07003098 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003099 cricket::WebRtcVoiceMediaChannel* media_channel =
3100 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003101 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102 EXPECT_TRUE(media_channel->AddRecvStream(
3103 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3104
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003105 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003106 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003107 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003108 EXPECT_EQ(0, s->received_packets());
3109 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3110 EXPECT_EQ(1, s->received_packets());
3111 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3112 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003113}
Minyue2013aec2015-05-13 14:14:42 +02003114
solenberg0a617e22015-10-20 15:49:38 -07003115// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003116// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003117TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003118 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003119 EXPECT_TRUE(AddRecvStream(kSsrcY));
3120 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003121 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003122 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3123 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3124 EXPECT_TRUE(AddRecvStream(kSsrcW));
3125 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003126}
3127
solenberg7602aab2016-11-14 11:30:07 -08003128TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3129 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003130 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003131 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003132 cricket::StreamParams::CreateLegacy(kSsrcY)));
3133 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3134 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3135 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003136 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003137 cricket::StreamParams::CreateLegacy(kSsrcW)));
3138 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3139 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003140}
stefan658910c2015-09-03 05:48:32 -07003141
deadbeef884f5852016-01-15 09:20:04 -08003142TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003143 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003144 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3145 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003146
3147 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003148 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3149 EXPECT_TRUE(AddRecvStream(kSsrcX));
3150 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003151
3152 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003153 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3154 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003155
3156 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003157 channel_->SetRawAudioSink(kSsrcX, nullptr);
3158 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003159}
3160
solenberg2100c0b2017-03-01 11:29:29 -08003161TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003162 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003163 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3164 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003165 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3166 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003167
3168 // Should be able to set a default sink even when no stream exists.
3169 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3170
solenberg2100c0b2017-03-01 11:29:29 -08003171 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3172 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003173 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003174 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003175
3176 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003177 channel_->SetRawAudioSink(kSsrc0, nullptr);
3178 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003179
3180 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003181 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3182 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003183
3184 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003185 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003186 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003187 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3188
3189 // Spawn another unsignaled stream - it should be assigned the default sink
3190 // and the previous unsignaled stream should lose it.
3191 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3192 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3193 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3194 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003195 if (kMaxUnsignaledRecvStreams > 1) {
3196 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3197 }
solenberg2100c0b2017-03-01 11:29:29 -08003198 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3199
3200 // Reset the default sink - the second unsignaled stream should lose it.
3201 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003202 if (kMaxUnsignaledRecvStreams > 1) {
3203 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3204 }
solenberg2100c0b2017-03-01 11:29:29 -08003205 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3206
3207 // Try setting the default sink while two streams exists.
3208 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003209 if (kMaxUnsignaledRecvStreams > 1) {
3210 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3211 }
solenberg2100c0b2017-03-01 11:29:29 -08003212 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3213
3214 // Try setting the sink for the first unsignaled stream using its known SSRC.
3215 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003216 if (kMaxUnsignaledRecvStreams > 1) {
3217 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3218 }
solenberg2100c0b2017-03-01 11:29:29 -08003219 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003220 if (kMaxUnsignaledRecvStreams > 1) {
3221 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3222 }
deadbeef884f5852016-01-15 09:20:04 -08003223}
3224
skvlad7a43d252016-03-22 15:32:27 -07003225// Test that, just like the video channel, the voice channel communicates the
3226// network state to the call.
3227TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003228 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003229
3230 EXPECT_EQ(webrtc::kNetworkUp,
3231 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3232 EXPECT_EQ(webrtc::kNetworkUp,
3233 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3234
3235 channel_->OnReadyToSend(false);
3236 EXPECT_EQ(webrtc::kNetworkDown,
3237 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3238 EXPECT_EQ(webrtc::kNetworkUp,
3239 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3240
3241 channel_->OnReadyToSend(true);
3242 EXPECT_EQ(webrtc::kNetworkUp,
3243 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3244 EXPECT_EQ(webrtc::kNetworkUp,
3245 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3246}
3247
aleloi18e0b672016-10-04 02:45:47 -07003248// Test that playout is still started after changing parameters
3249TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3250 SetupRecvStream();
3251 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003253
3254 // Changing RTP header extensions will recreate the AudioReceiveStream.
3255 cricket::AudioRecvParameters parameters;
3256 parameters.extensions.push_back(
3257 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3258 channel_->SetRecvParameters(parameters);
3259
solenberg2100c0b2017-03-01 11:29:29 -08003260 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003261}
3262
Zhi Huangfa266ef2017-12-13 10:27:46 -08003263// Tests when GetSources is called with non-existing ssrc, it will return an
3264// empty list of RtpSource without crashing.
3265TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3266 // Setup an recv stream with |kSsrcX|.
3267 SetupRecvStream();
3268 cricket::WebRtcVoiceMediaChannel* media_channel =
3269 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3270 // Call GetSources with |kSsrcY| which doesn't exist.
3271 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3272 EXPECT_EQ(0u, sources.size());
3273}
3274
stefan658910c2015-09-03 05:48:32 -07003275// Tests that the library initializes and shuts down properly.
3276TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003277 // If the VoiceEngine wants to gather available codecs early, that's fine but
3278 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003279 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003280 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003281 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003282 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003283 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003284 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003285 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003286 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003287 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003288 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003289 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3290 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003291 EXPECT_TRUE(channel != nullptr);
3292 delete channel;
solenbergff976312016-03-30 23:28:51 -07003293}
stefan658910c2015-09-03 05:48:32 -07003294
solenbergff976312016-03-30 23:28:51 -07003295// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003296TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3297 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003298 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003299 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003300 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003301 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003302 {
peaha9cc40b2017-06-29 08:32:09 -07003303 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003304 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003305 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003306 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003307 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003308 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003309 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003310 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003311 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003312 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3313 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3314 EXPECT_TRUE(channel != nullptr);
3315 delete channel;
3316 }
stefan658910c2015-09-03 05:48:32 -07003317}
3318
ossu20a4b3f2017-04-27 02:08:52 -07003319// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3320TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003321 // TODO(ossu): Why are the payload types of codecs with non-static payload
3322 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003323 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003324 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003325 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003326 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003327 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003328 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003329 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003330 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003331 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3332 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3333 (clockrate == 0 || codec.clockrate == clockrate);
3334 };
3335 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003336 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003337 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003338 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003339 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003340 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003341 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003342 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003343 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003344 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003345 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003346 EXPECT_EQ(126, codec.id);
3347 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3348 // Remove these checks once both send and receive side assigns payload types
3349 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003350 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003351 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003352 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003353 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003354 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003355 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003356 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(111, codec.id);
3358 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3359 EXPECT_EQ("10", codec.params.find("minptime")->second);
3360 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3361 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003362 }
3363 }
stefan658910c2015-09-03 05:48:32 -07003364}
3365
3366// Tests that VoE supports at least 32 channels
3367TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003368 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003369 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003370 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003371 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003372 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003373 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003374 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003375 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003376 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003377 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003378
3379 cricket::VoiceMediaChannel* channels[32];
3380 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003381 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003382 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3383 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003384 if (!channel)
3385 break;
stefan658910c2015-09-03 05:48:32 -07003386 channels[num_channels++] = channel;
3387 }
3388
tfarina5237aaf2015-11-10 23:44:30 -08003389 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003390 EXPECT_EQ(expected, num_channels);
3391
3392 while (num_channels > 0) {
3393 delete channels[--num_channels];
3394 }
stefan658910c2015-09-03 05:48:32 -07003395}
3396
3397// Test that we set our preferred codecs properly.
3398TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003399 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3400 // - Check that our builtin codecs are usable by Channel.
3401 // - The codecs provided by the engine is usable by Channel.
3402 // It does not check that the codecs in the RecvParameters are actually
3403 // what we sent in - though it's probably reasonable to expect so, if
3404 // SetRecvParameters returns true.
3405 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003406 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003407 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003408 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003409 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003410 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003411 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003412 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003413 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003414 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003415 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003416 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3417 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003418 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003419 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003420 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003421}
ossu9def8002017-02-09 05:14:32 -08003422
3423TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3424 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003425 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3426 {48000, 2, 16000, 10000, 20000}};
3427 spec1.info.allow_comfort_noise = false;
3428 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003429 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003430 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3431 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003432 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003433 specs.push_back(webrtc::AudioCodecSpec{
3434 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3435 {16000, 1, 13300}});
3436 specs.push_back(
3437 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3438 specs.push_back(
3439 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003440
ossueb1fde42017-05-02 06:46:30 -07003441 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3442 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3443 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003444 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003445 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003446 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003447 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003448
peaha9cc40b2017-06-29 08:32:09 -07003449 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003450 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003451 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003452 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003453 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003454 auto codecs = engine.recv_codecs();
3455 EXPECT_EQ(11, codecs.size());
3456
3457 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3458 // check the actual values safely, to provide better test results.
3459 auto get_codec =
3460 [&codecs](size_t index) -> const cricket::AudioCodec& {
3461 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3462 if (codecs.size() > index)
3463 return codecs[index];
3464 return missing_codec;
3465 };
3466
3467 // Ensure the general codecs are generated first and in order.
3468 for (size_t i = 0; i != specs.size(); ++i) {
3469 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3470 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3471 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3472 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3473 }
3474
3475 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003476 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003477 auto find_codec =
3478 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3479 for (size_t i = 0; i != codecs.size(); ++i) {
3480 const cricket::AudioCodec& codec = codecs[i];
3481 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3482 codec.clockrate == format.clockrate_hz &&
3483 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003484 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003485 }
3486 }
3487 return -1;
3488 };
3489
3490 // Ensure all supplementary codecs are generated last. Their internal ordering
3491 // is not important.
3492 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3493 const int num_specs = static_cast<int>(specs.size());
3494 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3495 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3496 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3497 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3498 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3499 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3500 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3501}