blob: 9b56dbf8267f0479872e3fc4799e349dea1e4bc8 [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;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700365 return channel_->SetRtpSendParameters(ssrc, parameters);
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());
solenberg2100c0b2017-03-01 11:29:29 -08001037 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001038}
1039
1040TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001041 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001042 // This test verifies that setting RtpParameters succeeds only if
1043 // the structure contains exactly one encoding.
1044 // TODO(skvlad): Update this test when we start supporting setting parameters
1045 // for each encoding individually.
1046
1047 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001048 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001049 // Two or more encodings should result in failure.
1050 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001051 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001052 // Zero encodings should also fail.
1053 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001055}
1056
1057// Changing the SSRC through RtpParameters is not allowed.
1058TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1059 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001060 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001061 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001062 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001063}
1064
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001065// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001066// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001067TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1068 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001069 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001071 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001072 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001073 ASSERT_EQ(1u, parameters.encodings.size());
1074 ASSERT_TRUE(parameters.encodings[0].active);
1075 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001076 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1077 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001078
1079 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001080 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001081 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001082 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1084 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085}
1086
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001087// Test that SetRtpSendParameters configures the correct encoding channel for
1088// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001089TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1090 SetupForMultiSendStream();
1091 // Create send streams.
1092 for (uint32_t ssrc : kSsrcs4) {
1093 EXPECT_TRUE(
1094 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1095 }
1096 // Configure one stream to be limited by the stream config, another to be
1097 // limited by the global max, and the third one with no per-stream limit
1098 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001099 SetGlobalMaxBitrate(kOpusCodec, 32000);
1100 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1101 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001102 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1103
ossu20a4b3f2017-04-27 02:08:52 -07001104 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1105 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1106 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001107
1108 // Remove the global cap; the streams should switch to their respective
1109 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001110 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001111 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1112 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1113 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001114}
1115
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001116// Test that GetRtpSendParameters returns the currently configured codecs.
1117TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001118 EXPECT_TRUE(SetupSendStream());
1119 cricket::AudioSendParameters parameters;
1120 parameters.codecs.push_back(kIsacCodec);
1121 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001122 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001123
solenberg2100c0b2017-03-01 11:29:29 -08001124 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001125 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001126 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1127 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001128}
1129
deadbeefcb443432016-12-12 11:12:36 -08001130// Test that GetRtpSendParameters returns an SSRC.
1131TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1132 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001134 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001135 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001136}
1137
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001139TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001140 EXPECT_TRUE(SetupSendStream());
1141 cricket::AudioSendParameters parameters;
1142 parameters.codecs.push_back(kIsacCodec);
1143 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001144 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001145
solenberg2100c0b2017-03-01 11:29:29 -08001146 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147
1148 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001149 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001152 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1153 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001154}
1155
minyuececec102017-03-27 13:04:25 -07001156// Test that max_bitrate_bps in send stream config gets updated correctly when
1157// SetRtpSendParameters is called.
1158TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1159 webrtc::test::ScopedFieldTrials override_field_trials(
1160 "WebRTC-Audio-SendSideBwe/Enabled/");
1161 EXPECT_TRUE(SetupSendStream());
1162 cricket::AudioSendParameters send_parameters;
1163 send_parameters.codecs.push_back(kOpusCodec);
1164 SetSendParameters(send_parameters);
1165
1166 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1167 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1168 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1169
1170 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001171 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001172 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1173
1174 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1175 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1176}
1177
Seth Hampson24722b32017-12-22 09:36:42 -08001178// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1179// a value <= 0, setting the parameters returns false.
1180TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1181 EXPECT_TRUE(SetupSendStream());
1182 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1183 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1184 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1185 rtp_parameters.encodings[0].bitrate_priority);
1186
1187 rtp_parameters.encodings[0].bitrate_priority = 0;
1188 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1189 rtp_parameters.encodings[0].bitrate_priority = -1.0;
1190 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1191}
1192
1193// Test that the bitrate_priority in the send stream config gets updated when
1194// SetRtpSendParameters is set for the VoiceMediaChannel.
1195TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1196 EXPECT_TRUE(SetupSendStream());
1197 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1198
1199 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1200 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1201 rtp_parameters.encodings[0].bitrate_priority);
1202 double new_bitrate_priority = 2.0;
1203 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
1204 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1205
1206 // The priority should get set for both the audio channel's rtp parameters
1207 // and the audio send stream's audio config.
1208 EXPECT_EQ(
1209 new_bitrate_priority,
1210 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1211 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1212}
1213
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001214// Test that GetRtpReceiveParameters returns the currently configured codecs.
1215TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1216 EXPECT_TRUE(SetupRecvStream());
1217 cricket::AudioRecvParameters parameters;
1218 parameters.codecs.push_back(kIsacCodec);
1219 parameters.codecs.push_back(kPcmuCodec);
1220 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1221
1222 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001223 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001224 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1225 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1226 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1227}
1228
deadbeefcb443432016-12-12 11:12:36 -08001229// Test that GetRtpReceiveParameters returns an SSRC.
1230TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1231 EXPECT_TRUE(SetupRecvStream());
1232 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001233 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001234 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001235 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001236}
1237
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001238// Test that if we set/get parameters multiple times, we get the same results.
1239TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1240 EXPECT_TRUE(SetupRecvStream());
1241 cricket::AudioRecvParameters parameters;
1242 parameters.codecs.push_back(kIsacCodec);
1243 parameters.codecs.push_back(kPcmuCodec);
1244 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1245
1246 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001247 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001248
1249 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001250 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001251
1252 // ... And this shouldn't change the params returned by
1253 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001254 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1255 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001256}
1257
deadbeef3bc15102017-04-20 19:25:07 -07001258// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1259// aren't signaled. It should return an empty "RtpEncodingParameters" when
1260// configured to receive an unsignaled stream and no packets have been received
1261// yet, and start returning the SSRC once a packet has been received.
1262TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1263 ASSERT_TRUE(SetupChannel());
1264 // Call necessary methods to configure receiving a default stream as
1265 // soon as it arrives.
1266 cricket::AudioRecvParameters parameters;
1267 parameters.codecs.push_back(kIsacCodec);
1268 parameters.codecs.push_back(kPcmuCodec);
1269 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1270
1271 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1272 // stream. Should return nothing.
1273 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1274
1275 // Set a sink for an unsignaled stream.
1276 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1277 // Value of "0" means "unsignaled stream".
1278 channel_->SetRawAudioSink(0, std::move(fake_sink));
1279
1280 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1281 // in this method means "unsignaled stream".
1282 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1283 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1284 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1285
1286 // Receive PCMU packet (SSRC=1).
1287 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1288
1289 // The |ssrc| member should still be unset.
1290 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1291 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1292 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1293}
1294
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295// Test that we apply codecs properly.
1296TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001297 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 cricket::AudioSendParameters parameters;
1299 parameters.codecs.push_back(kIsacCodec);
1300 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001301 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001302 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001303 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001304 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001305 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1306 EXPECT_EQ(96, send_codec_spec.payload_type);
1307 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1308 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1309 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001310 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001311 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312}
1313
ossu20a4b3f2017-04-27 02:08:52 -07001314// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1315// AudioSendStream.
1316TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001317 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001318 cricket::AudioSendParameters parameters;
1319 parameters.codecs.push_back(kIsacCodec);
1320 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001321 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001322 parameters.codecs[0].id = 96;
1323 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001324 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001325 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001326 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001327 // Calling SetSendCodec again with same codec which is already set.
1328 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001329 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001330 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001331}
1332
ossu20a4b3f2017-04-27 02:08:52 -07001333// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1334// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001335
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001336// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001338 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 cricket::AudioSendParameters parameters;
1340 parameters.codecs.push_back(kOpusCodec);
1341 parameters.codecs[0].bitrate = 0;
1342 parameters.codecs[0].clockrate = 50000;
1343 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001346// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
1352 parameters.codecs[0].channels = 0;
1353 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001356// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001358 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 cricket::AudioSendParameters parameters;
1360 parameters.codecs.push_back(kOpusCodec);
1361 parameters.codecs[0].bitrate = 0;
1362 parameters.codecs[0].channels = 0;
1363 parameters.codecs[0].params["stereo"] = "1";
1364 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365}
1366
1367// Test that if channel is 1 for opus and there's no stereo, we fail.
1368TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001369 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 cricket::AudioSendParameters parameters;
1371 parameters.codecs.push_back(kOpusCodec);
1372 parameters.codecs[0].bitrate = 0;
1373 parameters.codecs[0].channels = 1;
1374 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375}
1376
1377// Test that if channel is 1 for opus and stereo=0, we fail.
1378TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001379 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 cricket::AudioSendParameters parameters;
1381 parameters.codecs.push_back(kOpusCodec);
1382 parameters.codecs[0].bitrate = 0;
1383 parameters.codecs[0].channels = 1;
1384 parameters.codecs[0].params["stereo"] = "0";
1385 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386}
1387
1388// Test that if channel is 1 for opus and stereo=1, we fail.
1389TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001390 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 cricket::AudioSendParameters parameters;
1392 parameters.codecs.push_back(kOpusCodec);
1393 parameters.codecs[0].bitrate = 0;
1394 parameters.codecs[0].channels = 1;
1395 parameters.codecs[0].params["stereo"] = "1";
1396 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397}
1398
ossu20a4b3f2017-04-27 02:08:52 -07001399// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001401 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 cricket::AudioSendParameters parameters;
1403 parameters.codecs.push_back(kOpusCodec);
1404 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407}
1408
ossu20a4b3f2017-04-27 02:08:52 -07001409// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].bitrate = 0;
1415 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001416 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001417 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001418}
1419
ossu20a4b3f2017-04-27 02:08:52 -07001420// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001421TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001422 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001423 cricket::AudioSendParameters parameters;
1424 parameters.codecs.push_back(kOpusCodec);
1425 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001426 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001427 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001428 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001429 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001430
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001434}
1435
ossu20a4b3f2017-04-27 02:08:52 -07001436// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].bitrate = 0;
1442 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001443 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001444 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445}
1446
ossu20a4b3f2017-04-27 02:08:52 -07001447// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001453 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001455 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001456 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001457
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001459 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001460 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001461}
1462
ossu20a4b3f2017-04-27 02:08:52 -07001463// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001469 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001470 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1471 EXPECT_EQ(111, spec.payload_type);
1472 EXPECT_EQ(96000, spec.target_bitrate_bps);
1473 EXPECT_EQ("opus", spec.format.name);
1474 EXPECT_EQ(2, spec.format.num_channels);
1475 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476}
1477
ossu20a4b3f2017-04-27 02:08:52 -07001478// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].bitrate = 30000;
1484 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001485 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001486 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487}
1488
ossu20a4b3f2017-04-27 02:08:52 -07001489// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001491 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001492 cricket::AudioSendParameters parameters;
1493 parameters.codecs.push_back(kOpusCodec);
1494 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001495 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001496 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001497}
1498
ossu20a4b3f2017-04-27 02:08:52 -07001499// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001500TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001501 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 cricket::AudioSendParameters parameters;
1503 parameters.codecs.push_back(kOpusCodec);
1504 parameters.codecs[0].bitrate = 30000;
1505 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001506 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001507 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001508}
1509
stefan13f1a0a2016-11-30 07:22:58 -08001510TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1511 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1512 200000);
1513}
1514
1515TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1516 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1517}
1518
1519TEST_F(WebRtcVoiceEngineTestFake,
1520 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1521 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1522}
1523
1524TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1525 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1526}
1527
1528TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001529 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001530 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1531 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001532 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001533 SetSendParameters(send_parameters_);
1534 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1535 << "Setting max bitrate should keep previous min bitrate.";
1536 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1537 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001538 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001539}
1540
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001541// Test that we can enable NACK with opus as caller.
1542TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001543 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 cricket::AudioSendParameters parameters;
1545 parameters.codecs.push_back(kOpusCodec);
1546 parameters.codecs[0].AddFeedbackParam(
1547 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1548 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001549 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001550 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552}
1553
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001554// Test that we can enable NACK with opus as callee.
1555TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001556 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001557 cricket::AudioSendParameters parameters;
1558 parameters.codecs.push_back(kOpusCodec);
1559 parameters.codecs[0].AddFeedbackParam(
1560 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1561 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001562 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001564 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001565 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001566
1567 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001568 cricket::StreamParams::CreateLegacy(kSsrcX)));
1569 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001570}
1571
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572// Test that we can enable NACK on receive streams.
1573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001574 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001576 cricket::AudioSendParameters parameters;
1577 parameters.codecs.push_back(kOpusCodec);
1578 parameters.codecs[0].AddFeedbackParam(
1579 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1580 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1582 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001583 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001584 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1585 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001586}
1587
1588// Test that we can disable NACK.
1589TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001590 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001591 cricket::AudioSendParameters parameters;
1592 parameters.codecs.push_back(kOpusCodec);
1593 parameters.codecs[0].AddFeedbackParam(
1594 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1595 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 parameters.codecs.clear();
1600 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001601 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001602 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603}
1604
1605// Test that we can disable NACK on receive streams.
1606TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001608 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters parameters;
1610 parameters.codecs.push_back(kOpusCodec);
1611 parameters.codecs[0].AddFeedbackParam(
1612 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1613 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001614 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1616 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001618 parameters.codecs.clear();
1619 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001620 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001621 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1622 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623}
1624
1625// Test that NACK is enabled on a new receive stream.
1626TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001627 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001628 cricket::AudioSendParameters parameters;
1629 parameters.codecs.push_back(kIsacCodec);
1630 parameters.codecs.push_back(kCn16000Codec);
1631 parameters.codecs[0].AddFeedbackParam(
1632 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1633 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001635 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001636
solenberg2100c0b2017-03-01 11:29:29 -08001637 EXPECT_TRUE(AddRecvStream(kSsrcY));
1638 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1639 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1640 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001641}
1642
stefanba4c0e42016-02-04 04:12:24 -08001643TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001644 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001645 cricket::AudioSendParameters send_parameters;
1646 send_parameters.codecs.push_back(kOpusCodec);
1647 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001649
1650 cricket::AudioRecvParameters recv_parameters;
1651 recv_parameters.codecs.push_back(kIsacCodec);
1652 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001653 EXPECT_TRUE(AddRecvStream(kSsrcX));
1654 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001655 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001656 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001657
ossudedfd282016-06-14 07:12:39 -07001658 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001661 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001662 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001663}
1664
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001665// Test that we can switch back and forth between Opus and ISAC with CN.
1666TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001667 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001668
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 cricket::AudioSendParameters opus_parameters;
1670 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001672 {
ossu20a4b3f2017-04-27 02:08:52 -07001673 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1674 EXPECT_EQ(111, spec.payload_type);
1675 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001676 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters isac_parameters;
1679 isac_parameters.codecs.push_back(kIsacCodec);
1680 isac_parameters.codecs.push_back(kCn16000Codec);
1681 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001683 {
ossu20a4b3f2017-04-27 02:08:52 -07001684 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1685 EXPECT_EQ(103, spec.payload_type);
1686 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001687 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688
solenberg059fb442016-10-26 05:12:24 -07001689 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001690 {
ossu20a4b3f2017-04-27 02:08:52 -07001691 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1692 EXPECT_EQ(111, spec.payload_type);
1693 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001694 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001695}
1696
1697// Test that we handle various ways of specifying bitrate.
1698TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001699 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 cricket::AudioSendParameters parameters;
1701 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001703 {
ossu20a4b3f2017-04-27 02:08:52 -07001704 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1705 EXPECT_EQ(103, spec.payload_type);
1706 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1707 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001708 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001710 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001711 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001712 {
ossu20a4b3f2017-04-27 02:08:52 -07001713 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1714 EXPECT_EQ(103, spec.payload_type);
1715 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1716 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001717 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001720 {
ossu20a4b3f2017-04-27 02:08:52 -07001721 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1722 EXPECT_EQ(103, spec.payload_type);
1723 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1724 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001725 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001726
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001727 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001729 {
ossu20a4b3f2017-04-27 02:08:52 -07001730 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1731 EXPECT_EQ(0, spec.payload_type);
1732 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1733 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001734 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001738 {
ossu20a4b3f2017-04-27 02:08:52 -07001739 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1740 EXPECT_EQ(0, spec.payload_type);
1741 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1742 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001743 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 parameters.codecs[0] = kOpusCodec;
1746 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001747 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001748 {
ossu20a4b3f2017-04-27 02:08:52 -07001749 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1750 EXPECT_EQ(111, spec.payload_type);
1751 EXPECT_STREQ("opus", spec.format.name.c_str());
1752 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001753 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001754}
1755
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001756// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001758 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 cricket::AudioSendParameters parameters;
1760 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001761}
1762
1763// Test that we can set send codecs even with telephone-event codec as the first
1764// one on the list.
1765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001768 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001769 parameters.codecs.push_back(kIsacCodec);
1770 parameters.codecs.push_back(kPcmuCodec);
1771 parameters.codecs[0].id = 98; // DTMF
1772 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001773 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001774 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1775 EXPECT_EQ(96, spec.payload_type);
1776 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001777 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001778}
1779
solenberg31642aa2016-03-14 08:00:37 -07001780// Test that payload type range is limited for telephone-event codec.
1781TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001782 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001783 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001784 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001785 parameters.codecs.push_back(kIsacCodec);
1786 parameters.codecs[0].id = 0; // DTMF
1787 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001788 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001789 EXPECT_TRUE(channel_->CanInsertDtmf());
1790 parameters.codecs[0].id = 128; // DTMF
1791 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1792 EXPECT_FALSE(channel_->CanInsertDtmf());
1793 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001794 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001795 EXPECT_TRUE(channel_->CanInsertDtmf());
1796 parameters.codecs[0].id = -1; // DTMF
1797 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1798 EXPECT_FALSE(channel_->CanInsertDtmf());
1799}
1800
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001801// Test that we can set send codecs even with CN codec as the first
1802// one on the list.
1803TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001804 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 cricket::AudioSendParameters parameters;
1806 parameters.codecs.push_back(kCn16000Codec);
1807 parameters.codecs.push_back(kIsacCodec);
1808 parameters.codecs.push_back(kPcmuCodec);
1809 parameters.codecs[0].id = 98; // wideband CN
1810 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001811 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001812 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1813 EXPECT_EQ(96, send_codec_spec.payload_type);
1814 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001815 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816}
1817
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001818// Test that we set VAD and DTMF types correctly as caller.
1819TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001820 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001821 cricket::AudioSendParameters parameters;
1822 parameters.codecs.push_back(kIsacCodec);
1823 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs.push_back(kCn16000Codec);
1826 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001827 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001828 parameters.codecs[0].id = 96;
1829 parameters.codecs[2].id = 97; // wideband CN
1830 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001831 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001832 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1833 EXPECT_EQ(96, send_codec_spec.payload_type);
1834 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1835 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001837 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001838}
1839
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001840// Test that we set VAD and DTMF types correctly as callee.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001842 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 cricket::AudioSendParameters parameters;
1844 parameters.codecs.push_back(kIsacCodec);
1845 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001846 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kCn16000Codec);
1848 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001849 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001850 parameters.codecs[0].id = 96;
1851 parameters.codecs[2].id = 97; // wideband CN
1852 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001854 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001855 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001856
ossu20a4b3f2017-04-27 02:08:52 -07001857 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1858 EXPECT_EQ(96, send_codec_spec.payload_type);
1859 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1860 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001861 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001862 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001863}
1864
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001865// Test that we only apply VAD if we have a CN codec that matches the
1866// send codec clockrate.
1867TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001868 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001870 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 parameters.codecs.push_back(kIsacCodec);
1872 parameters.codecs.push_back(kCn16000Codec);
1873 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001875 {
ossu20a4b3f2017-04-27 02:08:52 -07001876 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1877 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1878 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001879 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001880 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001881 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001884 {
ossu20a4b3f2017-04-27 02:08:52 -07001885 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1886 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001887 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001888 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001889 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001892 {
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1895 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001897 }
Brave Yao5225dd82015-03-26 07:39:19 +08001898 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001899 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001900 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001901 {
ossu20a4b3f2017-04-27 02:08:52 -07001902 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1903 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001904 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001905 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001906}
1907
1908// Test that we perform case-insensitive matching of codec names.
1909TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001910 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 cricket::AudioSendParameters parameters;
1912 parameters.codecs.push_back(kIsacCodec);
1913 parameters.codecs.push_back(kPcmuCodec);
1914 parameters.codecs.push_back(kCn16000Codec);
1915 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001916 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001917 parameters.codecs[0].name = "iSaC";
1918 parameters.codecs[0].id = 96;
1919 parameters.codecs[2].id = 97; // wideband CN
1920 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001921 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001922 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1923 EXPECT_EQ(96, send_codec_spec.payload_type);
1924 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1925 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001926 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001927 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928}
1929
stefanba4c0e42016-02-04 04:12:24 -08001930class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1931 public:
1932 WebRtcVoiceEngineWithSendSideBweTest()
1933 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1934};
1935
1936TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1937 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001938 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001939 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001940 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1941 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1942 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001943 extension.id);
1944 return;
1945 }
1946 }
1947 FAIL() << "Transport sequence number extension not in header-extension list.";
1948}
1949
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001950// Test support for audio level header extension.
1951TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001952 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001953}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001954TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001955 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001956}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001957
solenbergd4adce42016-11-17 06:26:52 -08001958// Test support for transport sequence number header extension.
1959TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1960 TestSetSendRtpHeaderExtensions(
1961 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001962}
solenbergd4adce42016-11-17 06:26:52 -08001963TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1964 TestSetRecvRtpHeaderExtensions(
1965 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966}
1967
solenberg1ac56142015-10-13 03:58:19 -07001968// Test that we can create a channel and start sending on it.
1969TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(send_parameters_);
1972 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001973 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001974 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001975 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001976}
1977
1978// Test that a channel will send if and only if it has a source and is enabled
1979// for sending.
1980TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001981 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001982 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001983 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001984 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1986 SetAudioSend(kSsrcX, true, &fake_source_);
1987 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1988 SetAudioSend(kSsrcX, true, nullptr);
1989 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001990}
1991
solenberg94218532016-06-16 10:53:22 -07001992// Test that a channel is muted/unmuted.
1993TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1994 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001995 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001996 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1997 SetAudioSend(kSsrcX, true, nullptr);
1998 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1999 SetAudioSend(kSsrcX, false, nullptr);
2000 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002001}
2002
solenberg6d6e7c52016-04-13 09:07:30 -07002003// Test that SetSendParameters() does not alter a stream's send state.
2004TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2005 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002006 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002007
2008 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002009 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002010 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002011
2012 // Changing RTP header extensions will recreate the AudioSendStream.
2013 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002014 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002015 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002016 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002017
2018 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002019 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002020 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002021
2022 // Changing RTP header extensions will recreate the AudioSendStream.
2023 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002024 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002025 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002026}
2027
solenberg1ac56142015-10-13 03:58:19 -07002028// Test that we can create a channel and start playing out on it.
2029TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002030 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002031 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002032 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002033 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002034 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002035 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002036}
2037
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038// Test that we can add and remove send streams.
2039TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2040 SetupForMultiSendStream();
2041
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002043 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044
solenbergc96df772015-10-21 13:01:53 -07002045 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002047 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002048 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002050 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051 }
tfarina5237aaf2015-11-10 23:44:30 -08002052 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002053
solenbergc96df772015-10-21 13:01:53 -07002054 // Delete the send streams.
2055 for (uint32_t ssrc : kSsrcs4) {
2056 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002057 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002058 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 }
solenbergc96df772015-10-21 13:01:53 -07002060 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061}
2062
2063// Test SetSendCodecs correctly configure the codecs in all send streams.
2064TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2065 SetupForMultiSendStream();
2066
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002067 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002068 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002070 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071 }
2072
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002073 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002074 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002075 parameters.codecs.push_back(kIsacCodec);
2076 parameters.codecs.push_back(kCn16000Codec);
2077 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002078 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079
2080 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002081 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002082 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2083 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002084 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2085 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2086 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002087 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089
minyue7a973442016-10-20 03:27:12 -07002090 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002091 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002092 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002093 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002094 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2095 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002096 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2097 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002098 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 }
2100}
2101
2102// Test we can SetSend on all send streams correctly.
2103TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2104 SetupForMultiSendStream();
2105
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002106 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002107 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002109 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002110 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002111 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 }
2113
2114 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002115 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002116 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002118 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002119 }
2120
2121 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002122 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002123 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002125 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 }
2127}
2128
2129// Test we can set the correct statistics on all send streams.
2130TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2131 SetupForMultiSendStream();
2132
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002134 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002135 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002136 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137 }
solenberg85a04962015-10-27 03:35:21 -07002138
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002139 // Create a receive stream to check that none of the send streams end up in
2140 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002141 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002142
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002144 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002145 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002146 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002147
solenberg85a04962015-10-27 03:35:21 -07002148 // Check stats for the added streams.
2149 {
2150 cricket::VoiceMediaInfo info;
2151 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152
solenberg85a04962015-10-27 03:35:21 -07002153 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002154 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002155 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002156 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002157 }
hbos1acfbd22016-11-17 23:43:29 -08002158 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002159
2160 // We have added one receive stream. We should see empty stats.
2161 EXPECT_EQ(info.receivers.size(), 1u);
2162 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163 }
solenberg1ac56142015-10-13 03:58:19 -07002164
solenberg2100c0b2017-03-01 11:29:29 -08002165 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002166 {
2167 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002169 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002170 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002171 EXPECT_EQ(0u, info.receivers.size());
2172 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002173
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002174 // Deliver a new packet - a default receive stream should be created and we
2175 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002176 {
2177 cricket::VoiceMediaInfo info;
2178 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2179 SetAudioReceiveStreamStats();
2180 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002181 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002182 EXPECT_EQ(1u, info.receivers.size());
2183 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002184 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002185 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002186}
2187
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002188// Test that we can add and remove receive streams, and do proper send/playout.
2189// We can receive on multiple streams while sending one stream.
2190TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002191 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002192
solenberg1ac56142015-10-13 03:58:19 -07002193 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002194 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002195 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002196
solenberg1ac56142015-10-13 03:58:19 -07002197 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002198 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002199 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002200 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002201
solenberg1ac56142015-10-13 03:58:19 -07002202 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002203 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204
2205 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002206 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2207 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2208 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002209
2210 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002211 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002212 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002213
2214 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002215 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2217 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218
aleloi84ef6152016-08-04 05:28:21 -07002219 // Restart playout and make sure recv streams are played out.
2220 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002221 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2222 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002223
aleloi84ef6152016-08-04 05:28:21 -07002224 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2226 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002227}
2228
wu@webrtc.org97077a32013-10-25 21:18:33 +00002229TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002230 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002231 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2232 .Times(1)
2233 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002234 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2235 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002236 send_parameters_.options.tx_agc_target_dbov = 3;
2237 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2238 send_parameters_.options.tx_agc_limiter = true;
2239 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002240 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2241 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2242 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002243 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002244}
2245
minyue6b825df2016-10-31 04:08:32 -07002246TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2247 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002248 send_parameters_.options.audio_network_adaptor = true;
2249 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002250 SetSendParameters(send_parameters_);
2251 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002252 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002253}
2254
2255TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2256 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002257 send_parameters_.options.audio_network_adaptor = true;
2258 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002259 SetSendParameters(send_parameters_);
2260 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002261 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002262 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002263 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002264 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002265 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002266}
2267
2268TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2269 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002270 send_parameters_.options.audio_network_adaptor = true;
2271 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002272 SetSendParameters(send_parameters_);
2273 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002274 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275 const int initial_num = call_.GetNumCreatedSendStreams();
2276 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002277 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002278 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2279 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002280 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002281 // AudioSendStream not expected to be recreated.
2282 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2283 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002284 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002285}
2286
michaelt6672b262017-01-11 10:17:59 -08002287class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2288 : public WebRtcVoiceEngineTestFake {
2289 public:
2290 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2291 : WebRtcVoiceEngineTestFake(
2292 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2293 "Enabled/") {}
2294};
2295
2296TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2297 EXPECT_TRUE(SetupSendStream());
2298 cricket::AudioSendParameters parameters;
2299 parameters.codecs.push_back(kOpusCodec);
2300 SetSendParameters(parameters);
2301 const int initial_num = call_.GetNumCreatedSendStreams();
2302 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2303
2304 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2305 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002306 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2307 constexpr int kMinOverheadBps =
2308 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002309
2310 constexpr int kOpusMinBitrateBps = 6000;
2311 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002312 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002313 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002314 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002315 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002316
Oskar Sundbom78807582017-11-16 11:09:55 +01002317 parameters.options.audio_network_adaptor = true;
2318 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002319 SetSendParameters(parameters);
2320
ossu11bfc532017-02-16 05:37:06 -08002321 constexpr int kMinOverheadWithAnaBps =
2322 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002323
2324 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002325 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002326
minyuececec102017-03-27 13:04:25 -07002327 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002328 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002329}
2330
minyuececec102017-03-27 13:04:25 -07002331// This test is similar to
2332// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2333// additional field trial.
2334TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2335 SetRtpSendParameterUpdatesMaxBitrate) {
2336 EXPECT_TRUE(SetupSendStream());
2337 cricket::AudioSendParameters send_parameters;
2338 send_parameters.codecs.push_back(kOpusCodec);
2339 SetSendParameters(send_parameters);
2340
2341 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2342 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2343 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2344
2345 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002346 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002347 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2348
2349 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2350#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2351 constexpr int kMinOverhead = 3333;
2352#else
2353 constexpr int kMinOverhead = 6666;
2354#endif
2355 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2356}
2357
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002358// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002359// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002360TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002361 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002362 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363}
2364
2365TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2366 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002367 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002368 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002369 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002370 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002371 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002372 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002373 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374
solenberg85a04962015-10-27 03:35:21 -07002375 // Check stats for the added streams.
2376 {
2377 cricket::VoiceMediaInfo info;
2378 EXPECT_EQ(true, channel_->GetStats(&info));
2379
2380 // We have added one send stream. We should see the stats we've set.
2381 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002382 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002383 // We have added one receive stream. We should see empty stats.
2384 EXPECT_EQ(info.receivers.size(), 1u);
2385 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2386 }
solenberg1ac56142015-10-13 03:58:19 -07002387
solenberg566ef242015-11-06 15:34:49 -08002388 // Start sending - this affects some reported stats.
2389 {
2390 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002391 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002392 EXPECT_EQ(true, channel_->GetStats(&info));
2393 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002394 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002395 }
2396
solenberg2100c0b2017-03-01 11:29:29 -08002397 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002398 {
2399 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002400 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002401 EXPECT_EQ(true, channel_->GetStats(&info));
2402 EXPECT_EQ(1u, info.senders.size());
2403 EXPECT_EQ(0u, info.receivers.size());
2404 }
solenberg1ac56142015-10-13 03:58:19 -07002405
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002406 // Deliver a new packet - a default receive stream should be created and we
2407 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002408 {
2409 cricket::VoiceMediaInfo info;
2410 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2411 SetAudioReceiveStreamStats();
2412 EXPECT_EQ(true, channel_->GetStats(&info));
2413 EXPECT_EQ(1u, info.senders.size());
2414 EXPECT_EQ(1u, info.receivers.size());
2415 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002416 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002417 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002421// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002424 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2425 EXPECT_TRUE(AddRecvStream(kSsrcY));
2426 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that the local SSRC is the same on sending and receiving channels if the
2430// receive channel is created before the send channel.
2431TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002433 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002435 cricket::StreamParams::CreateLegacy(kSsrcX)));
2436 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2437 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438}
2439
2440// Test that we can properly receive packets.
2441TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002442 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002443 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002445
2446 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2447 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448}
2449
2450// Test that we can properly receive packets on multiple streams.
2451TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002452 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002453 const uint32_t ssrc1 = 1;
2454 const uint32_t ssrc2 = 2;
2455 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002456 EXPECT_TRUE(AddRecvStream(ssrc1));
2457 EXPECT_TRUE(AddRecvStream(ssrc2));
2458 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002460 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002461 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002463 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464 }
mflodman3d7db262016-04-29 00:57:13 -07002465
2466 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2467 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2468 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2469
2470 EXPECT_EQ(s1.received_packets(), 0);
2471 EXPECT_EQ(s2.received_packets(), 0);
2472 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002473
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002475 EXPECT_EQ(s1.received_packets(), 0);
2476 EXPECT_EQ(s2.received_packets(), 0);
2477 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002478
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002480 EXPECT_EQ(s1.received_packets(), 1);
2481 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2482 EXPECT_EQ(s2.received_packets(), 0);
2483 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_EQ(s1.received_packets(), 1);
2487 EXPECT_EQ(s2.received_packets(), 1);
2488 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2489 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002490
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002492 EXPECT_EQ(s1.received_packets(), 1);
2493 EXPECT_EQ(s2.received_packets(), 1);
2494 EXPECT_EQ(s3.received_packets(), 1);
2495 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002496
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2498 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2499 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500}
2501
solenberg2100c0b2017-03-01 11:29:29 -08002502// Test that receiving on an unsignaled stream works (a stream is created).
2503TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002504 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002505 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2506
solenberg7e63ef02015-11-20 00:19:43 -08002507 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002508
2509 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002510 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2511 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002512}
2513
solenberg2100c0b2017-03-01 11:29:29 -08002514// Test that receiving N unsignaled stream works (streams will be created), and
2515// that packets are forwarded to them all.
2516TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002517 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002518 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002519 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2520
solenberg2100c0b2017-03-01 11:29:29 -08002521 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002522 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002523 rtc::SetBE32(&packet[8], ssrc);
2524 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002525
solenberg2100c0b2017-03-01 11:29:29 -08002526 // Verify we have one new stream for each loop iteration.
2527 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002528 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2529 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002530 }
mflodman3d7db262016-04-29 00:57:13 -07002531
solenberg2100c0b2017-03-01 11:29:29 -08002532 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002533 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002534 rtc::SetBE32(&packet[8], ssrc);
2535 DeliverPacket(packet, sizeof(packet));
2536
solenbergebb349d2017-03-13 05:46:15 -07002537 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002538 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2539 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2540 }
2541
2542 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2543 constexpr uint32_t kAnotherSsrc = 667;
2544 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002545 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002546
2547 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002548 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002549 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002550 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002551 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2552 EXPECT_EQ(2, streams[i]->received_packets());
2553 }
2554 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2555 EXPECT_EQ(1, streams[i]->received_packets());
2556 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002557 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002558}
2559
solenberg2100c0b2017-03-01 11:29:29 -08002560// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002561// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002562TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002563 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002564 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002565 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2566
2567 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002568 const uint32_t signaled_ssrc = 1;
2569 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002570 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2573 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002574 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002575
2576 // Note that the first unknown SSRC cannot be 0, because we only support
2577 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002578 const uint32_t unsignaled_ssrc = 7011;
2579 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002580 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002581 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2582 packet, sizeof(packet)));
2583 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2584
2585 DeliverPacket(packet, sizeof(packet));
2586 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2587
2588 rtc::SetBE32(&packet[8], signaled_ssrc);
2589 DeliverPacket(packet, sizeof(packet));
2590 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2591 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002592}
2593
solenberg4904fb62017-02-17 12:01:14 -08002594// Two tests to verify that adding a receive stream with the same SSRC as a
2595// previously added unsignaled stream will only recreate underlying stream
2596// objects if the stream parameters have changed.
2597TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2598 EXPECT_TRUE(SetupChannel());
2599
2600 // Spawn unsignaled stream with SSRC=1.
2601 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2602 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2603 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2604 sizeof(kPcmuFrame)));
2605
2606 // Verify that the underlying stream object in Call is not recreated when a
2607 // stream with SSRC=1 is added.
2608 const auto& streams = call_.GetAudioReceiveStreams();
2609 EXPECT_EQ(1, streams.size());
2610 int audio_receive_stream_id = streams.front()->id();
2611 EXPECT_TRUE(AddRecvStream(1));
2612 EXPECT_EQ(1, streams.size());
2613 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2614}
2615
2616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2617 EXPECT_TRUE(SetupChannel());
2618
2619 // Spawn unsignaled stream with SSRC=1.
2620 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2621 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2622 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2623 sizeof(kPcmuFrame)));
2624
2625 // Verify that the underlying stream object in Call *is* recreated when a
2626 // stream with SSRC=1 is added, and which has changed stream parameters.
2627 const auto& streams = call_.GetAudioReceiveStreams();
2628 EXPECT_EQ(1, streams.size());
2629 int audio_receive_stream_id = streams.front()->id();
2630 cricket::StreamParams stream_params;
2631 stream_params.ssrcs.push_back(1);
2632 stream_params.sync_label = "sync_label";
2633 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2634 EXPECT_EQ(1, streams.size());
2635 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2636}
2637
solenberg1ac56142015-10-13 03:58:19 -07002638// Test that AddRecvStream creates new stream.
2639TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002640 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002641 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642}
2643
2644// Test that after adding a recv stream, we do not decode more codecs than
2645// those previously passed into SetRecvCodecs.
2646TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002648 cricket::AudioRecvParameters parameters;
2649 parameters.codecs.push_back(kIsacCodec);
2650 parameters.codecs.push_back(kPcmuCodec);
2651 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002652 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002653 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2654 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2655 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002656}
2657
2658// Test that we properly clean up any streams that were added, even if
2659// not explicitly removed.
2660TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002661 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002662 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002663 EXPECT_TRUE(AddRecvStream(1));
2664 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002665
2666 EXPECT_EQ(1, call_.GetAudioSendStreams().size());
2667 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002668 delete channel_;
2669 channel_ = NULL;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002670 EXPECT_EQ(0, call_.GetAudioSendStreams().size());
2671 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002672}
2673
wu@webrtc.org78187522013-10-07 23:32:02 +00002674TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002675 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002676 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002677}
2678
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002679TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002680 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002681 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002682 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002683}
2684
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002685// Test the InsertDtmf on default send stream as caller.
2686TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002687 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688}
2689
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002690// Test the InsertDtmf on default send stream as callee
2691TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002692 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002693}
2694
2695// Test the InsertDtmf on specified send stream as caller.
2696TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002697 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002698}
2699
2700// Test the InsertDtmf on specified send stream as callee.
2701TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002702 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703}
2704
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002706 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002707 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002708 EXPECT_CALL(adm_,
2709 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2710 EXPECT_CALL(adm_,
2711 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2712 EXPECT_CALL(adm_,
2713 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002714
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002715 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2716 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717
solenberg246b8172015-12-08 09:50:23 -08002718 // Nothing set in AudioOptions, so everything should be as default.
2719 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002720 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002721 EXPECT_TRUE(IsHighPassFilterEnabled());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002722 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2723 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002724
2725 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002726 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2727 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002728 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002729 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730
2731 // Turn echo cancellation back on, with settings, and make sure
2732 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002733 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2734 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002735 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002736 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002738 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2739 // control.
solenberg76377c52017-02-21 00:54:31 -08002740 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2741 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002742 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002743 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002744
2745 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002746 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2747 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002748 send_parameters_.options.delay_agnostic_aec = false;
2749 send_parameters_.options.extended_filter_aec = false;
2750 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002752
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002753 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002754 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2755 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002756 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002757 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002758
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002762 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002763 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002764 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002765 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766
2767 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002768 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2769 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002770 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002772 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002775 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002776 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002778 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002779 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002780 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002781 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002783 send_parameters_.options.noise_suppression = false;
2784 send_parameters_.options.highpass_filter = false;
2785 send_parameters_.options.typing_detection = false;
2786 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002787 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002788 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789
solenberg1ac56142015-10-13 03:58:19 -07002790 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002791 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002793 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002794 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002795 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002796 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2797 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002798 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799}
2800
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002802 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002803 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002804 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002805 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002806 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002807 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002808 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002809 EXPECT_CALL(adm_,
2810 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2811 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2812 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002813 webrtc::AudioProcessing::Config apm_config;
2814 EXPECT_CALL(*apm_, GetConfig())
2815 .Times(10)
2816 .WillRepeatedly(ReturnPointee(&apm_config));
2817 EXPECT_CALL(*apm_, ApplyConfig(_))
2818 .Times(10)
2819 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002820 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002821
kwiberg686a8ef2016-02-26 03:00:35 -08002822 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002823 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002824 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002825 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002826 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002827 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002828
2829 // Have to add a stream to make SetSend work.
2830 cricket::StreamParams stream1;
2831 stream1.ssrcs.push_back(1);
2832 channel1->AddSendStream(stream1);
2833 cricket::StreamParams stream2;
2834 stream2.ssrcs.push_back(2);
2835 channel2->AddSendStream(stream2);
2836
2837 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002838 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002839 parameters_options_all.options.echo_cancellation = true;
2840 parameters_options_all.options.auto_gain_control = true;
2841 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002842 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2843 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002844 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002845 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002846 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002847 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002848 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002849 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002850 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002851 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852
2853 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002854 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002855 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002856 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2857 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002858 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002859 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002860 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002861 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002862 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002863 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002864 expected_options.echo_cancellation = true;
2865 expected_options.auto_gain_control = true;
2866 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002867 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
2869 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002870 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002871 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2873 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002874 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002875 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002876 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002877 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002878 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002879 expected_options.echo_cancellation = true;
2880 expected_options.auto_gain_control = false;
2881 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002882 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002883
solenberg76377c52017-02-21 00:54:31 -08002884 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002886 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002888 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002889 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002890 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
solenberg76377c52017-02-21 00:54:31 -08002892 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002894 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002896 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002898 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899
solenberg76377c52017-02-21 00:54:31 -08002900 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002902 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002903 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002904 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002905 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002906 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002909 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2910 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002911 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2912 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002917 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002919 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002920 expected_options.echo_cancellation = true;
2921 expected_options.auto_gain_control = false;
2922 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002923 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924}
2925
wu@webrtc.orgde305012013-10-31 15:40:38 +00002926// This test verifies DSCP settings are properly applied on voice media channel.
2927TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002928 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002929 cricket::FakeNetworkInterface network_interface;
2930 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002931 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002932
peahb1c9d1d2017-07-25 15:45:24 -07002933 webrtc::AudioProcessing::Config apm_config;
2934 EXPECT_CALL(*apm_, GetConfig())
2935 .Times(3)
2936 .WillRepeatedly(ReturnPointee(&apm_config));
2937 EXPECT_CALL(*apm_, ApplyConfig(_))
2938 .Times(3)
2939 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002940 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002941
solenbergbc37fc82016-04-04 09:54:44 -07002942 channel.reset(
2943 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002944 channel->SetInterface(&network_interface);
2945 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2946 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2947
2948 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002949 channel.reset(
2950 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002951 channel->SetInterface(&network_interface);
2952 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2953
2954 // Verify that setting the option to false resets the
2955 // DiffServCodePoint.
2956 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002957 channel.reset(
2958 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002959 channel->SetInterface(&network_interface);
2960 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2961 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2962
2963 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002964}
2965
solenberg4bac9c52015-10-09 02:32:53 -07002966TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002967 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002968 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002969 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002970 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002972 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2973 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2974 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002975}
2976
solenberg2100c0b2017-03-01 11:29:29 -08002977TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002978 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002979
2980 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002981 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002982 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2983
2984 // Should remember the volume "2" which will be set on new unsignaled streams,
2985 // and also set the gain to 2 on existing unsignaled streams.
2986 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2987 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2988
2989 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2990 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2991 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2992 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2993 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2994 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2995
2996 // Setting gain with SSRC=0 should affect all unsignaled streams.
2997 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002998 if (kMaxUnsignaledRecvStreams > 1) {
2999 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3000 }
solenberg2100c0b2017-03-01 11:29:29 -08003001 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3002
3003 // Setting gain on an individual stream affects only that.
3004 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003005 if (kMaxUnsignaledRecvStreams > 1) {
3006 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3007 }
solenberg2100c0b2017-03-01 11:29:29 -08003008 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003009}
3010
pbos8fc7fa72015-07-15 08:02:58 -07003011TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003012 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003013 const std::string kSyncLabel = "AvSyncLabel";
3014
solenbergff976312016-03-30 23:28:51 -07003015 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003016 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3017 sp.sync_label = kSyncLabel;
3018 // Creating two channels to make sure that sync label is set properly for both
3019 // the default voice channel and following ones.
3020 EXPECT_TRUE(channel_->AddRecvStream(sp));
3021 sp.ssrcs[0] += 1;
3022 EXPECT_TRUE(channel_->AddRecvStream(sp));
3023
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003024 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003025 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003026 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003027 << "SyncGroup should be set based on sync_label";
3028 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003029 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003030 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003031}
3032
solenberg3a941542015-11-16 07:34:50 -08003033// TODO(solenberg): Remove, once recv streams are configured through Call.
3034// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003035TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003036 // Test that setting the header extensions results in the expected state
3037 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003038 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003039 ssrcs.push_back(223);
3040 ssrcs.push_back(224);
3041
solenbergff976312016-03-30 23:28:51 -07003042 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003043 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003044 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003045 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003046 cricket::StreamParams::CreateLegacy(ssrc)));
3047 }
3048
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003049 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003050 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003051 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003052 EXPECT_NE(nullptr, s);
3053 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3054 }
3055
3056 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003057 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003058 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003059 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003060 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003061 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003062 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003063 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003064 EXPECT_NE(nullptr, s);
3065 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003066 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3067 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003068 for (const auto& s_ext : s_exts) {
3069 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003070 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003071 }
3072 }
3073 }
3074 }
3075
3076 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003077 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003078 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003079 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003080 EXPECT_NE(nullptr, s);
3081 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3082 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003083}
3084
3085TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3086 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003087 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003088 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003089 static const unsigned char kRtcp[] = {
3090 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3091 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3094 };
jbaucheec21bd2016-03-20 06:15:43 -07003095 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003096
solenbergff976312016-03-30 23:28:51 -07003097 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 cricket::WebRtcVoiceMediaChannel* media_channel =
3099 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003100 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003101 EXPECT_TRUE(media_channel->AddRecvStream(
3102 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3103
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003104 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003106 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107 EXPECT_EQ(0, s->received_packets());
3108 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3109 EXPECT_EQ(1, s->received_packets());
3110 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3111 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112}
Minyue2013aec2015-05-13 14:14:42 +02003113
solenberg0a617e22015-10-20 15:49:38 -07003114// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003115// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003116TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003117 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003118 EXPECT_TRUE(AddRecvStream(kSsrcY));
3119 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003120 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003121 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3122 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3123 EXPECT_TRUE(AddRecvStream(kSsrcW));
3124 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003125}
3126
solenberg7602aab2016-11-14 11:30:07 -08003127TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3128 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003129 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003130 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003131 cricket::StreamParams::CreateLegacy(kSsrcY)));
3132 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3133 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3134 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003135 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003136 cricket::StreamParams::CreateLegacy(kSsrcW)));
3137 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3138 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003139}
stefan658910c2015-09-03 05:48:32 -07003140
deadbeef884f5852016-01-15 09:20:04 -08003141TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003142 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003143 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3144 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003145
3146 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003147 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3148 EXPECT_TRUE(AddRecvStream(kSsrcX));
3149 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003150
3151 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003152 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3153 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003154
3155 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003156 channel_->SetRawAudioSink(kSsrcX, nullptr);
3157 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003158}
3159
solenberg2100c0b2017-03-01 11:29:29 -08003160TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003161 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003162 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3163 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003164 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3165 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003166
3167 // Should be able to set a default sink even when no stream exists.
3168 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3169
solenberg2100c0b2017-03-01 11:29:29 -08003170 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3171 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003172 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003173 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003174
3175 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003176 channel_->SetRawAudioSink(kSsrc0, nullptr);
3177 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003178
3179 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003180 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3181 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003182
3183 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003184 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003185 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003186 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3187
3188 // Spawn another unsignaled stream - it should be assigned the default sink
3189 // and the previous unsignaled stream should lose it.
3190 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3191 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3192 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3193 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003194 if (kMaxUnsignaledRecvStreams > 1) {
3195 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3196 }
solenberg2100c0b2017-03-01 11:29:29 -08003197 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3198
3199 // Reset the default sink - the second unsignaled stream should lose it.
3200 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003201 if (kMaxUnsignaledRecvStreams > 1) {
3202 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3203 }
solenberg2100c0b2017-03-01 11:29:29 -08003204 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3205
3206 // Try setting the default sink while two streams exists.
3207 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003208 if (kMaxUnsignaledRecvStreams > 1) {
3209 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3210 }
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3212
3213 // Try setting the sink for the first unsignaled stream using its known SSRC.
3214 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003215 if (kMaxUnsignaledRecvStreams > 1) {
3216 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3217 }
solenberg2100c0b2017-03-01 11:29:29 -08003218 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003219 if (kMaxUnsignaledRecvStreams > 1) {
3220 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3221 }
deadbeef884f5852016-01-15 09:20:04 -08003222}
3223
skvlad7a43d252016-03-22 15:32:27 -07003224// Test that, just like the video channel, the voice channel communicates the
3225// network state to the call.
3226TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003227 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003228
3229 EXPECT_EQ(webrtc::kNetworkUp,
3230 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3231 EXPECT_EQ(webrtc::kNetworkUp,
3232 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3233
3234 channel_->OnReadyToSend(false);
3235 EXPECT_EQ(webrtc::kNetworkDown,
3236 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3237 EXPECT_EQ(webrtc::kNetworkUp,
3238 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3239
3240 channel_->OnReadyToSend(true);
3241 EXPECT_EQ(webrtc::kNetworkUp,
3242 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3243 EXPECT_EQ(webrtc::kNetworkUp,
3244 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3245}
3246
aleloi18e0b672016-10-04 02:45:47 -07003247// Test that playout is still started after changing parameters
3248TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3249 SetupRecvStream();
3250 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003251 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003252
3253 // Changing RTP header extensions will recreate the AudioReceiveStream.
3254 cricket::AudioRecvParameters parameters;
3255 parameters.extensions.push_back(
3256 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3257 channel_->SetRecvParameters(parameters);
3258
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003260}
3261
Zhi Huangfa266ef2017-12-13 10:27:46 -08003262// Tests when GetSources is called with non-existing ssrc, it will return an
3263// empty list of RtpSource without crashing.
3264TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3265 // Setup an recv stream with |kSsrcX|.
3266 SetupRecvStream();
3267 cricket::WebRtcVoiceMediaChannel* media_channel =
3268 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3269 // Call GetSources with |kSsrcY| which doesn't exist.
3270 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3271 EXPECT_EQ(0u, sources.size());
3272}
3273
stefan658910c2015-09-03 05:48:32 -07003274// Tests that the library initializes and shuts down properly.
3275TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003276 // If the VoiceEngine wants to gather available codecs early, that's fine but
3277 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003278 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003279 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003280 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003281 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003282 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003283 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003284 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003285 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003286 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003287 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003288 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3289 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003290 EXPECT_TRUE(channel != nullptr);
3291 delete channel;
solenbergff976312016-03-30 23:28:51 -07003292}
stefan658910c2015-09-03 05:48:32 -07003293
solenbergff976312016-03-30 23:28:51 -07003294// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003295TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3296 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003297 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003298 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003299 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003300 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003301 {
peaha9cc40b2017-06-29 08:32:09 -07003302 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003303 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003304 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003305 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003306 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003307 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003308 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003309 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003310 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003311 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3312 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3313 EXPECT_TRUE(channel != nullptr);
3314 delete channel;
3315 }
stefan658910c2015-09-03 05:48:32 -07003316}
3317
ossu20a4b3f2017-04-27 02:08:52 -07003318// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3319TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003320 // TODO(ossu): Why are the payload types of codecs with non-static payload
3321 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003322 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003323 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003324 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003325 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003326 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003327 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003328 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003329 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003330 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3331 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3332 (clockrate == 0 || codec.clockrate == clockrate);
3333 };
3334 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003335 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003336 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003337 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003338 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003339 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003340 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003341 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003342 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003343 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003344 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003345 EXPECT_EQ(126, codec.id);
3346 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3347 // Remove these checks once both send and receive side assigns payload types
3348 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003349 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003350 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003351 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003352 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003353 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003354 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003355 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003356 EXPECT_EQ(111, codec.id);
3357 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3358 EXPECT_EQ("10", codec.params.find("minptime")->second);
3359 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3360 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003361 }
3362 }
stefan658910c2015-09-03 05:48:32 -07003363}
3364
3365// Tests that VoE supports at least 32 channels
3366TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003367 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003368 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003369 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003370 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003371 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003372 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003373 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003374 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003375 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003376 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003377
3378 cricket::VoiceMediaChannel* channels[32];
3379 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003380 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003381 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3382 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003383 if (!channel)
3384 break;
stefan658910c2015-09-03 05:48:32 -07003385 channels[num_channels++] = channel;
3386 }
3387
tfarina5237aaf2015-11-10 23:44:30 -08003388 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003389 EXPECT_EQ(expected, num_channels);
3390
3391 while (num_channels > 0) {
3392 delete channels[--num_channels];
3393 }
stefan658910c2015-09-03 05:48:32 -07003394}
3395
3396// Test that we set our preferred codecs properly.
3397TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003398 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3399 // - Check that our builtin codecs are usable by Channel.
3400 // - The codecs provided by the engine is usable by Channel.
3401 // It does not check that the codecs in the RecvParameters are actually
3402 // what we sent in - though it's probably reasonable to expect so, if
3403 // SetRecvParameters returns true.
3404 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003405 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003406 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003407 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003408 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003409 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003410 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003411 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003412 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003413 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003414 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003415 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3416 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003417 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003418 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003419 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003420}
ossu9def8002017-02-09 05:14:32 -08003421
3422TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3423 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003424 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3425 {48000, 2, 16000, 10000, 20000}};
3426 spec1.info.allow_comfort_noise = false;
3427 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003428 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003429 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3430 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003431 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003432 specs.push_back(webrtc::AudioCodecSpec{
3433 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3434 {16000, 1, 13300}});
3435 specs.push_back(
3436 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3437 specs.push_back(
3438 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003439
ossueb1fde42017-05-02 06:46:30 -07003440 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3441 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3442 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003443 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003444 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003445 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003446 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003447
peaha9cc40b2017-06-29 08:32:09 -07003448 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003449 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003450 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003451 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003452 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003453 auto codecs = engine.recv_codecs();
3454 EXPECT_EQ(11, codecs.size());
3455
3456 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3457 // check the actual values safely, to provide better test results.
3458 auto get_codec =
3459 [&codecs](size_t index) -> const cricket::AudioCodec& {
3460 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3461 if (codecs.size() > index)
3462 return codecs[index];
3463 return missing_codec;
3464 };
3465
3466 // Ensure the general codecs are generated first and in order.
3467 for (size_t i = 0; i != specs.size(); ++i) {
3468 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3469 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3470 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3471 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3472 }
3473
3474 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003475 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003476 auto find_codec =
3477 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3478 for (size_t i = 0; i != codecs.size(); ++i) {
3479 const cricket::AudioCodec& codec = codecs[i];
3480 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3481 codec.clockrate == format.clockrate_hz &&
3482 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003483 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003484 }
3485 }
3486 return -1;
3487 };
3488
3489 // Ensure all supplementary codecs are generated last. Their internal ordering
3490 // is not important.
3491 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3492 const int num_specs = static_cast<int>(specs.size());
3493 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3494 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3495 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3496 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3497 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3498 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3499 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3500}