blob: 4df63b398c0db0736064f2ae2f78e10643eed9dd [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"
16#include "call/call.h"
17#include "logging/rtc_event_log/rtc_event_log.h"
18#include "media/base/fakemediaengine.h"
19#include "media/base/fakenetworkinterface.h"
20#include "media/base/fakertp.h"
21#include "media/base/mediaconstants.h"
22#include "media/engine/fakewebrtccall.h"
23#include "media/engine/fakewebrtcvoiceengine.h"
24#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());
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100135 cricket::FakeWebRtcVoiceEngine voe;
solenbergff976312016-03-30 23:28:51 -0700136 EXPECT_FALSE(voe.IsInited());
137 {
ossuc54071d2016-08-17 02:45:41 -0700138 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700139 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700140 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100141 new cricket::VoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700142 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700143 EXPECT_TRUE(voe.IsInited());
144 }
145 EXPECT_FALSE(voe.IsInited());
146}
147
deadbeef884f5852016-01-15 09:20:04 -0800148class FakeAudioSink : public webrtc::AudioSinkInterface {
149 public:
150 void OnData(const Data& audio) override {}
151};
152
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800153class FakeAudioSource : public cricket::AudioSource {
154 void SetSink(Sink* sink) override {}
155};
156
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157class WebRtcVoiceEngineTestFake : public testing::Test {
158 public:
stefanba4c0e42016-02-04 04:12:24 -0800159 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
160
161 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700162 : apm_(new rtc::RefCountedObject<
163 StrictMock<webrtc::test::MockAudioProcessing>>()),
164 apm_gc_(*apm_->gain_control()),
165 apm_ec_(*apm_->echo_cancellation()),
166 apm_ns_(*apm_->noise_suppression()),
167 apm_vd_(*apm_->voice_detection()),
168 call_(webrtc::Call::Config(&event_log_)),
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100169 voe_(),
skvlad11a9cbf2016-10-07 11:53:05 -0700170 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800171 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700172 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800173 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700174 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
175 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700176 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700177 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800178 // Default Options.
179 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
180 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100181 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
182 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800183 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100184 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
185 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800186 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
187 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800188 // Init does not overwrite default AGC config.
189 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
190 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
191 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800192 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
193 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700194 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800195 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700196 // factories. Those tests should probably be moved elsewhere.
197 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
198 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100199 engine_.reset(new cricket::WebRtcVoiceEngine(
200 &adm_, encoder_factory, decoder_factory, nullptr, apm_,
201 new cricket::VoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700202 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200203 send_parameters_.codecs.push_back(kPcmuCodec);
204 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100205
solenberg76377c52017-02-21 00:54:31 -0800206 // Default Options.
207 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 }
solenberg8189b022016-06-14 12:13:00 -0700209
solenbergff976312016-03-30 23:28:51 -0700210 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700211 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700212 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
213 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200214 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000215 }
solenberg8189b022016-06-14 12:13:00 -0700216
solenbergff976312016-03-30 23:28:51 -0700217 bool SetupRecvStream() {
218 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700219 return false;
220 }
solenberg2100c0b2017-03-01 11:29:29 -0800221 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700222 }
solenberg8189b022016-06-14 12:13:00 -0700223
solenbergff976312016-03-30 23:28:51 -0700224 bool SetupSendStream() {
225 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000226 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 }
solenberg2100c0b2017-03-01 11:29:29 -0800228 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800229 return false;
230 }
peaha9cc40b2017-06-29 08:32:09 -0700231 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800232 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
solenberg8189b022016-06-14 12:13:00 -0700234
235 bool AddRecvStream(uint32_t ssrc) {
236 EXPECT_TRUE(channel_);
237 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
238 }
239
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000240 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700241 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700242 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800243 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
244 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700245 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800246 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 }
solenberg8189b022016-06-14 12:13:00 -0700248
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700250 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000251 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 }
solenberg8189b022016-06-14 12:13:00 -0700253
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200254 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 }
257
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100258 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
259 const auto* send_stream = call_.GetAudioSendStream(ssrc);
260 EXPECT_TRUE(send_stream);
261 return *send_stream;
262 }
263
deadbeef884f5852016-01-15 09:20:04 -0800264 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
265 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
266 EXPECT_TRUE(recv_stream);
267 return *recv_stream;
268 }
269
solenberg3a941542015-11-16 07:34:50 -0800270 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800271 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800272 }
273
solenberg7add0582015-11-20 09:59:34 -0800274 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800275 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800276 }
277
solenberg059fb442016-10-26 05:12:24 -0700278 void SetSend(bool enable) {
279 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700280 if (enable) {
281 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
282 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
283 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700284 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700285 }
solenberg059fb442016-10-26 05:12:24 -0700286 channel_->SetSend(enable);
287 }
288
289 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700290 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700291 ASSERT_TRUE(channel_);
292 EXPECT_TRUE(channel_->SetSendParameters(params));
293 }
294
minyue6b825df2016-10-31 04:08:32 -0700295 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
296 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700297 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700298 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700299 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700300 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700301 }
302 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700303 }
304
solenbergffbbcac2016-11-17 05:25:37 -0800305 void TestInsertDtmf(uint32_t ssrc, bool caller,
306 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700307 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000308 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700309 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 // send stream.
311 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800312 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700316 SetSendParameters(send_parameters_);
317 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800319 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800320 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700321 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000323
324 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700325 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000327 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800328 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329 }
330
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800332 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100334 // Test send.
335 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800336 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100337 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800339 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800340 EXPECT_EQ(codec.id, telephone_event.payload_type);
341 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100342 EXPECT_EQ(2, telephone_event.event_code);
343 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344 }
345
346 // Test that send bandwidth is set correctly.
347 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000348 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
349 // |expected_result| is the expected result from SetMaxSendBandwidth().
350 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700351 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
352 int max_bitrate,
353 bool expected_result,
354 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200355 cricket::AudioSendParameters parameters;
356 parameters.codecs.push_back(codec);
357 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700358 if (expected_result) {
359 SetSendParameters(parameters);
360 } else {
361 EXPECT_FALSE(channel_->SetSendParameters(parameters));
362 }
solenberg2100c0b2017-03-01 11:29:29 -0800363 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 }
365
skvlade0d46372016-04-07 22:59:22 -0700366 // Sets the per-stream maximum bitrate limit for the specified SSRC.
367 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700368 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700369 EXPECT_EQ(1UL, parameters.encodings.size());
370
Oskar Sundbom78807582017-11-16 11:09:55 +0100371 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700372 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700373 }
374
solenberg059fb442016-10-26 05:12:24 -0700375 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700376 cricket::AudioSendParameters send_parameters;
377 send_parameters.codecs.push_back(codec);
378 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700379 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700380 }
381
ossu20a4b3f2017-04-27 02:08:52 -0700382 void CheckSendCodecBitrate(int32_t ssrc,
383 const char expected_name[],
384 int expected_bitrate) {
385 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
386 EXPECT_EQ(expected_name, spec->format.name);
387 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700388 }
389
ossu20a4b3f2017-04-27 02:08:52 -0700390 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
391 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700392 }
393
minyue6b825df2016-10-31 04:08:32 -0700394 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
395 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
396 }
397
skvlade0d46372016-04-07 22:59:22 -0700398 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
399 int global_max,
400 int stream_max,
401 bool expected_result,
402 int expected_codec_bitrate) {
403 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800404 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700405
406 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700407 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800408 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700409
410 // Verify that reading back the parameters gives results
411 // consistent with the Set() result.
412 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800413 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700414 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
415 EXPECT_EQ(expected_result ? stream_max : -1,
416 resulting_parameters.encodings[0].max_bitrate_bps);
417
418 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800419 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700420 }
421
stefan13f1a0a2016-11-30 07:22:58 -0800422 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
423 int expected_min_bitrate_bps,
424 const char* start_bitrate_kbps,
425 int expected_start_bitrate_bps,
426 const char* max_bitrate_kbps,
427 int expected_max_bitrate_bps) {
428 EXPECT_TRUE(SetupSendStream());
429 auto& codecs = send_parameters_.codecs;
430 codecs.clear();
431 codecs.push_back(kOpusCodec);
432 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
433 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
435 SetSendParameters(send_parameters_);
436
437 EXPECT_EQ(expected_min_bitrate_bps,
438 call_.GetConfig().bitrate_config.min_bitrate_bps);
439 EXPECT_EQ(expected_start_bitrate_bps,
440 call_.GetConfig().bitrate_config.start_bitrate_bps);
441 EXPECT_EQ(expected_max_bitrate_bps,
442 call_.GetConfig().bitrate_config.max_bitrate_bps);
443 }
444
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000445 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700446 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000447
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000448 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800449 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000450
451 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700452 send_parameters_.extensions.push_back(
453 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700454 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800455 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000456
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000457 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200458 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700459 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800460 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000461
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000462 // Ensure extension is set properly.
463 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700464 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700465 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800466 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
467 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
468 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000469
solenberg7add0582015-11-20 09:59:34 -0800470 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000471 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800472 cricket::StreamParams::CreateLegacy(kSsrcY)));
473 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
474 call_.GetAudioSendStream(kSsrcY));
475 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
476 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
477 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000478
479 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200480 send_parameters_.codecs.push_back(kPcmuCodec);
481 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700482 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485 }
486
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000487 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700488 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800491 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492
493 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700494 recv_parameters_.extensions.push_back(
495 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800496 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800497 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000498
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000499 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800500 recv_parameters_.extensions.clear();
501 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800502 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000503
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000504 // Ensure extension is set properly.
505 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700506 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800507 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800508 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
509 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
510 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000511
solenberg7add0582015-11-20 09:59:34 -0800512 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800513 EXPECT_TRUE(AddRecvStream(kSsrcY));
514 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
515 call_.GetAudioReceiveStream(kSsrcY));
516 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
517 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
518 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000519
520 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800521 recv_parameters_.extensions.clear();
522 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800523 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000525 }
526
solenberg85a04962015-10-27 03:35:21 -0700527 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
528 webrtc::AudioSendStream::Stats stats;
529 stats.local_ssrc = 12;
530 stats.bytes_sent = 345;
531 stats.packets_sent = 678;
532 stats.packets_lost = 9012;
533 stats.fraction_lost = 34.56f;
534 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100535 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700536 stats.ext_seqnum = 789;
537 stats.jitter_ms = 12;
538 stats.rtt_ms = 345;
539 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100540 stats.apm_statistics.delay_median_ms = 234;
541 stats.apm_statistics.delay_standard_deviation_ms = 567;
542 stats.apm_statistics.echo_return_loss = 890;
543 stats.apm_statistics.echo_return_loss_enhancement = 1234;
544 stats.apm_statistics.residual_echo_likelihood = 0.432f;
545 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100546 stats.ana_statistics.bitrate_action_counter = 321;
547 stats.ana_statistics.channel_action_counter = 432;
548 stats.ana_statistics.dtx_action_counter = 543;
549 stats.ana_statistics.fec_action_counter = 654;
550 stats.ana_statistics.frame_length_increase_counter = 765;
551 stats.ana_statistics.frame_length_decrease_counter = 876;
552 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700553 stats.typing_noise_detected = true;
554 return stats;
555 }
556 void SetAudioSendStreamStats() {
557 for (auto* s : call_.GetAudioSendStreams()) {
558 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200559 }
solenberg85a04962015-10-27 03:35:21 -0700560 }
solenberg566ef242015-11-06 15:34:49 -0800561 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
562 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700563 const auto stats = GetAudioSendStreamStats();
564 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
565 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
566 EXPECT_EQ(info.packets_sent, stats.packets_sent);
567 EXPECT_EQ(info.packets_lost, stats.packets_lost);
568 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
569 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800570 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700571 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
572 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
573 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
574 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100575 EXPECT_EQ(info.apm_statistics.delay_median_ms,
576 stats.apm_statistics.delay_median_ms);
577 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
578 stats.apm_statistics.delay_standard_deviation_ms);
579 EXPECT_EQ(info.apm_statistics.echo_return_loss,
580 stats.apm_statistics.echo_return_loss);
581 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
582 stats.apm_statistics.echo_return_loss_enhancement);
583 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
584 stats.apm_statistics.residual_echo_likelihood);
585 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
586 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700587 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
588 stats.ana_statistics.bitrate_action_counter);
589 EXPECT_EQ(info.ana_statistics.channel_action_counter,
590 stats.ana_statistics.channel_action_counter);
591 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
592 stats.ana_statistics.dtx_action_counter);
593 EXPECT_EQ(info.ana_statistics.fec_action_counter,
594 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700595 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
596 stats.ana_statistics.frame_length_increase_counter);
597 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
598 stats.ana_statistics.frame_length_decrease_counter);
599 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
600 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800601 EXPECT_EQ(info.typing_noise_detected,
602 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700603 }
604
605 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
606 webrtc::AudioReceiveStream::Stats stats;
607 stats.remote_ssrc = 123;
608 stats.bytes_rcvd = 456;
609 stats.packets_rcvd = 768;
610 stats.packets_lost = 101;
611 stats.fraction_lost = 23.45f;
612 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100613 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700614 stats.ext_seqnum = 678;
615 stats.jitter_ms = 901;
616 stats.jitter_buffer_ms = 234;
617 stats.jitter_buffer_preferred_ms = 567;
618 stats.delay_estimate_ms = 890;
619 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700620 stats.total_samples_received = 5678901;
621 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200622 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200623 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700624 stats.expand_rate = 5.67f;
625 stats.speech_expand_rate = 8.90f;
626 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200627 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700628 stats.accelerate_rate = 4.56f;
629 stats.preemptive_expand_rate = 7.89f;
630 stats.decoding_calls_to_silence_generator = 12;
631 stats.decoding_calls_to_neteq = 345;
632 stats.decoding_normal = 67890;
633 stats.decoding_plc = 1234;
634 stats.decoding_cng = 5678;
635 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700636 stats.decoding_muted_output = 3456;
637 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200638 return stats;
639 }
640 void SetAudioReceiveStreamStats() {
641 for (auto* s : call_.GetAudioReceiveStreams()) {
642 s->SetStats(GetAudioReceiveStreamStats());
643 }
644 }
645 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700646 const auto stats = GetAudioReceiveStreamStats();
647 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
648 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
649 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
650 EXPECT_EQ(info.packets_lost, stats.packets_lost);
651 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
652 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800653 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700654 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
655 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
656 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200657 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700658 stats.jitter_buffer_preferred_ms);
659 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
660 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700661 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
662 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200663 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200664 EXPECT_EQ(info.jitter_buffer_delay_seconds,
665 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700666 EXPECT_EQ(info.expand_rate, stats.expand_rate);
667 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
668 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200669 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700670 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
671 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200672 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700673 stats.decoding_calls_to_silence_generator);
674 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
675 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
676 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
677 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
678 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700679 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700680 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200681 }
hbos1acfbd22016-11-17 23:43:29 -0800682 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
683 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
684 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
685 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
686 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
687 codec.ToCodecParameters());
688 }
689 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
690 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
691 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
692 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
693 codec.ToCodecParameters());
694 }
695 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200696
peah8271d042016-11-22 07:24:52 -0800697 bool IsHighPassFilterEnabled() {
698 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
699 }
700
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700702 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700703 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800704 webrtc::test::MockGainControl& apm_gc_;
705 webrtc::test::MockEchoCancellation& apm_ec_;
706 webrtc::test::MockNoiseSuppression& apm_ns_;
707 webrtc::test::MockVoiceDetection& apm_vd_;
skvlad11a9cbf2016-10-07 11:53:05 -0700708 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200709 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700711 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700712 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200713 cricket::AudioSendParameters send_parameters_;
714 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800715 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700716 webrtc::AudioProcessing::Config apm_config_;
717
stefanba4c0e42016-02-04 04:12:24 -0800718 private:
719 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720};
721
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722// Tests that we can create and destroy a channel.
723TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700724 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725}
726
solenberg31fec402016-05-06 02:13:12 -0700727// Test that we can add a send stream and that it has the correct defaults.
728TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
729 EXPECT_TRUE(SetupChannel());
730 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800731 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
732 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
733 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700734 EXPECT_EQ("", config.rtp.c_name);
735 EXPECT_EQ(0u, config.rtp.extensions.size());
736 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
737 config.send_transport);
738}
739
740// Test that we can add a receive stream and that it has the correct defaults.
741TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
742 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800743 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700744 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800745 GetRecvStreamConfig(kSsrcX);
746 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700747 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
748 EXPECT_FALSE(config.rtp.transport_cc);
749 EXPECT_EQ(0u, config.rtp.extensions.size());
750 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
751 config.rtcp_send_transport);
752 EXPECT_EQ("", config.sync_group);
753}
754
stefanba4c0e42016-02-04 04:12:24 -0800755TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700756 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800757 bool opus_found = false;
758 for (cricket::AudioCodec codec : codecs) {
759 if (codec.name == "opus") {
760 EXPECT_TRUE(HasTransportCc(codec));
761 opus_found = true;
762 }
763 }
764 EXPECT_TRUE(opus_found);
765}
766
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767// Test that we set our inbound codecs properly, including changing PT.
768TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700769 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200770 cricket::AudioRecvParameters parameters;
771 parameters.codecs.push_back(kIsacCodec);
772 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800773 parameters.codecs.push_back(kTelephoneEventCodec1);
774 parameters.codecs.push_back(kTelephoneEventCodec2);
775 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200776 parameters.codecs[2].id = 126;
777 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800778 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700779 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
780 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
781 {{0, {"PCMU", 8000, 1}},
782 {106, {"ISAC", 16000, 1}},
783 {126, {"telephone-event", 8000, 1}},
784 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
787// Test that we fail to set an unknown inbound codec.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200790 cricket::AudioRecvParameters parameters;
791 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700792 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200793 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794}
795
796// Test that we fail if we have duplicate types in the inbound list.
797TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700798 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200799 cricket::AudioRecvParameters parameters;
800 parameters.codecs.push_back(kIsacCodec);
801 parameters.codecs.push_back(kCn16000Codec);
802 parameters.codecs[1].id = kIsacCodec.id;
803 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that we can decode OPUS without stereo parameters.
807TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700808 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200809 cricket::AudioRecvParameters parameters;
810 parameters.codecs.push_back(kIsacCodec);
811 parameters.codecs.push_back(kPcmuCodec);
812 parameters.codecs.push_back(kOpusCodec);
813 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800814 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700815 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
816 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
817 {{0, {"PCMU", 8000, 1}},
818 {103, {"ISAC", 16000, 1}},
819 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820}
821
822// Test that we can decode OPUS with stereo = 0.
823TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700824 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200825 cricket::AudioRecvParameters parameters;
826 parameters.codecs.push_back(kIsacCodec);
827 parameters.codecs.push_back(kPcmuCodec);
828 parameters.codecs.push_back(kOpusCodec);
829 parameters.codecs[2].params["stereo"] = "0";
830 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800831 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700832 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
833 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
834 {{0, {"PCMU", 8000, 1}},
835 {103, {"ISAC", 16000, 1}},
836 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839// Test that we can decode OPUS with stereo = 1.
840TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700841 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200842 cricket::AudioRecvParameters parameters;
843 parameters.codecs.push_back(kIsacCodec);
844 parameters.codecs.push_back(kPcmuCodec);
845 parameters.codecs.push_back(kOpusCodec);
846 parameters.codecs[2].params["stereo"] = "1";
847 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800848 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700849 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
850 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
851 {{0, {"PCMU", 8000, 1}},
852 {103, {"ISAC", 16000, 1}},
853 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854}
855
856// Test that changes to recv codecs are applied to all streams.
857TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700858 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200859 cricket::AudioRecvParameters parameters;
860 parameters.codecs.push_back(kIsacCodec);
861 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800862 parameters.codecs.push_back(kTelephoneEventCodec1);
863 parameters.codecs.push_back(kTelephoneEventCodec2);
864 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200865 parameters.codecs[2].id = 126;
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700867 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
868 EXPECT_TRUE(AddRecvStream(ssrc));
869 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
870 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
871 {{0, {"PCMU", 8000, 1}},
872 {106, {"ISAC", 16000, 1}},
873 {126, {"telephone-event", 8000, 1}},
874 {107, {"telephone-event", 32000, 1}}})));
875 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876}
877
878TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700879 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200880 cricket::AudioRecvParameters parameters;
881 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800882 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200883 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884
solenberg2100c0b2017-03-01 11:29:29 -0800885 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800886 ASSERT_EQ(1, dm.count(106));
887 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888}
889
890// Test that we can apply the same set of codecs again while playing.
891TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700892 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200893 cricket::AudioRecvParameters parameters;
894 parameters.codecs.push_back(kIsacCodec);
895 parameters.codecs.push_back(kCn16000Codec);
896 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700897 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200898 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
deadbeefcb383672017-04-26 16:28:42 -0700900 // Remapping a payload type to a different codec should fail.
901 parameters.codecs[0] = kOpusCodec;
902 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800904 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905}
906
907// Test that we can add a codec while playing.
908TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700909 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200910 cricket::AudioRecvParameters parameters;
911 parameters.codecs.push_back(kIsacCodec);
912 parameters.codecs.push_back(kCn16000Codec);
913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700914 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200916 parameters.codecs.push_back(kOpusCodec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800918 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919}
920
deadbeefcb383672017-04-26 16:28:42 -0700921// Test that we accept adding the same codec with a different payload type.
922// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
923TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
924 EXPECT_TRUE(SetupRecvStream());
925 cricket::AudioRecvParameters parameters;
926 parameters.codecs.push_back(kIsacCodec);
927 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
928
929 ++parameters.codecs[0].id;
930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
931}
932
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700934 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000936 // Test that when autobw is enabled, bitrate is kept as the default
937 // value. autobw is enabled for the following tests because the target
938 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
940 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700941 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942
943 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700944 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
ossu20a4b3f2017-04-27 02:08:52 -0700946 // opus, default bitrate == 32000 in mono.
947 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948}
949
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000950TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700954 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
955 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700956 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700959 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
960 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
961 // Rates above the max (510000) should be capped.
962 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000965TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700966 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000967
968 // Test that we can only set a maximum bitrate for a fixed-rate codec
969 // if it's bigger than the fixed rate.
970
971 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700972 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
973 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000979}
980
981TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700982 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200983 const int kDesiredBitrate = 128000;
984 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700985 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200986 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700987 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000988
989 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800990 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000991
solenberg2100c0b2017-03-01 11:29:29 -0800992 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000993}
994
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995// Test that bitrate cannot be set for CBR codecs.
996// Bitrate is ignored if it is higher than the fixed bitrate.
997// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700999 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000
1001 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001002 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001003 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001004
1005 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008
1009 send_parameters_.max_bandwidth_bps = 128;
1010 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012}
1013
skvlade0d46372016-04-07 22:59:22 -07001014// Test that the per-stream bitrate limit and the global
1015// bitrate limit both apply.
1016TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1017 EXPECT_TRUE(SetupSendStream());
1018
ossu20a4b3f2017-04-27 02:08:52 -07001019 // opus, default bitrate == 32000.
1020 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001021 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1022 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1023 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1024
1025 // CBR codecs allow both maximums to exceed the bitrate.
1026 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1027 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1029 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1030
1031 // CBR codecs don't allow per stream maximums to be too low.
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1034}
1035
1036// Test that an attempt to set RtpParameters for a stream that does not exist
1037// fails.
1038TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1039 EXPECT_TRUE(SetupChannel());
1040 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001041 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001042 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1043
1044 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001045 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001046}
1047
1048TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001049 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001050 // This test verifies that setting RtpParameters succeeds only if
1051 // the structure contains exactly one encoding.
1052 // TODO(skvlad): Update this test when we start supporting setting parameters
1053 // for each encoding individually.
1054
1055 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001056 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001057 // Two or more encodings should result in failure.
1058 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001059 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001060 // Zero encodings should also fail.
1061 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001062 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001063}
1064
1065// Changing the SSRC through RtpParameters is not allowed.
1066TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1067 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001068 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001069 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001071}
1072
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001073// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001074// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001075TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1076 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001077 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001081 ASSERT_EQ(1u, parameters.encodings.size());
1082 ASSERT_TRUE(parameters.encodings[0].active);
1083 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001084 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1085 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086
1087 // Now change it back to active and verify we resume sending.
1088 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001089 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1090 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091}
1092
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001093// Test that SetRtpSendParameters configures the correct encoding channel for
1094// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001095TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1096 SetupForMultiSendStream();
1097 // Create send streams.
1098 for (uint32_t ssrc : kSsrcs4) {
1099 EXPECT_TRUE(
1100 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1101 }
1102 // Configure one stream to be limited by the stream config, another to be
1103 // limited by the global max, and the third one with no per-stream limit
1104 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001105 SetGlobalMaxBitrate(kOpusCodec, 32000);
1106 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1107 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001108 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1109
ossu20a4b3f2017-04-27 02:08:52 -07001110 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1111 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1112 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001113
1114 // Remove the global cap; the streams should switch to their respective
1115 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001116 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001117 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1118 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1119 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001120}
1121
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001122// Test that GetRtpSendParameters returns the currently configured codecs.
1123TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001124 EXPECT_TRUE(SetupSendStream());
1125 cricket::AudioSendParameters parameters;
1126 parameters.codecs.push_back(kIsacCodec);
1127 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001128 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129
solenberg2100c0b2017-03-01 11:29:29 -08001130 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001132 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1133 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001134}
1135
deadbeefcb443432016-12-12 11:12:36 -08001136// Test that GetRtpSendParameters returns an SSRC.
1137TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1138 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001139 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001140 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001141 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001142}
1143
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001144// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001145TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001146 EXPECT_TRUE(SetupSendStream());
1147 cricket::AudioSendParameters parameters;
1148 parameters.codecs.push_back(kIsacCodec);
1149 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001150 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151
solenberg2100c0b2017-03-01 11:29:29 -08001152 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001153
1154 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001155 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001158 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1159 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160}
1161
minyuececec102017-03-27 13:04:25 -07001162// Test that max_bitrate_bps in send stream config gets updated correctly when
1163// SetRtpSendParameters is called.
1164TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1165 webrtc::test::ScopedFieldTrials override_field_trials(
1166 "WebRTC-Audio-SendSideBwe/Enabled/");
1167 EXPECT_TRUE(SetupSendStream());
1168 cricket::AudioSendParameters send_parameters;
1169 send_parameters.codecs.push_back(kOpusCodec);
1170 SetSendParameters(send_parameters);
1171
1172 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1173 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1174 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1175
1176 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001177 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001178 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1179
1180 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1181 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1182}
1183
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001184// Test that GetRtpReceiveParameters returns the currently configured codecs.
1185TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1186 EXPECT_TRUE(SetupRecvStream());
1187 cricket::AudioRecvParameters parameters;
1188 parameters.codecs.push_back(kIsacCodec);
1189 parameters.codecs.push_back(kPcmuCodec);
1190 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1191
1192 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001193 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001194 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1195 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1196 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1197}
1198
deadbeefcb443432016-12-12 11:12:36 -08001199// Test that GetRtpReceiveParameters returns an SSRC.
1200TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1201 EXPECT_TRUE(SetupRecvStream());
1202 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001203 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001204 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001205 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001206}
1207
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001208// Test that if we set/get parameters multiple times, we get the same results.
1209TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1210 EXPECT_TRUE(SetupRecvStream());
1211 cricket::AudioRecvParameters parameters;
1212 parameters.codecs.push_back(kIsacCodec);
1213 parameters.codecs.push_back(kPcmuCodec);
1214 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1215
1216 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001217 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001218
1219 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001220 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221
1222 // ... And this shouldn't change the params returned by
1223 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001224 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1225 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001226}
1227
deadbeef3bc15102017-04-20 19:25:07 -07001228// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1229// aren't signaled. It should return an empty "RtpEncodingParameters" when
1230// configured to receive an unsignaled stream and no packets have been received
1231// yet, and start returning the SSRC once a packet has been received.
1232TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1233 ASSERT_TRUE(SetupChannel());
1234 // Call necessary methods to configure receiving a default stream as
1235 // soon as it arrives.
1236 cricket::AudioRecvParameters parameters;
1237 parameters.codecs.push_back(kIsacCodec);
1238 parameters.codecs.push_back(kPcmuCodec);
1239 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1240
1241 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1242 // stream. Should return nothing.
1243 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1244
1245 // Set a sink for an unsignaled stream.
1246 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1247 // Value of "0" means "unsignaled stream".
1248 channel_->SetRawAudioSink(0, std::move(fake_sink));
1249
1250 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1251 // in this method means "unsignaled stream".
1252 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1253 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1254 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1255
1256 // Receive PCMU packet (SSRC=1).
1257 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1258
1259 // The |ssrc| member should still be unset.
1260 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1261 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1262 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1263}
1264
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001265// Test that we apply codecs properly.
1266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001267 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001268 cricket::AudioSendParameters parameters;
1269 parameters.codecs.push_back(kIsacCodec);
1270 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001271 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001272 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001273 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001274 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001275 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1276 EXPECT_EQ(96, send_codec_spec.payload_type);
1277 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1278 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1279 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001280 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001281 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001282}
1283
ossu20a4b3f2017-04-27 02:08:52 -07001284// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1285// AudioSendStream.
1286TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001287 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001288 cricket::AudioSendParameters parameters;
1289 parameters.codecs.push_back(kIsacCodec);
1290 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001291 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001292 parameters.codecs[0].id = 96;
1293 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001294 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001295 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001296 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001297 // Calling SetSendCodec again with same codec which is already set.
1298 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001299 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001300 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001301}
1302
ossu20a4b3f2017-04-27 02:08:52 -07001303// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1304// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001305
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001306// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001308 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001309 cricket::AudioSendParameters parameters;
1310 parameters.codecs.push_back(kOpusCodec);
1311 parameters.codecs[0].bitrate = 0;
1312 parameters.codecs[0].clockrate = 50000;
1313 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001314}
1315
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001316// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001317TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001318 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001319 cricket::AudioSendParameters parameters;
1320 parameters.codecs.push_back(kOpusCodec);
1321 parameters.codecs[0].bitrate = 0;
1322 parameters.codecs[0].channels = 0;
1323 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324}
1325
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001326// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001328 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001329 cricket::AudioSendParameters parameters;
1330 parameters.codecs.push_back(kOpusCodec);
1331 parameters.codecs[0].bitrate = 0;
1332 parameters.codecs[0].channels = 0;
1333 parameters.codecs[0].params["stereo"] = "1";
1334 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
1337// Test that if channel is 1 for opus and there's no stereo, we fail.
1338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].channels = 1;
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
1347// Test that if channel is 1 for opus and stereo=0, we fail.
1348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
1353 parameters.codecs[0].channels = 1;
1354 parameters.codecs[0].params["stereo"] = "0";
1355 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
1358// Test that if channel is 1 for opus and stereo=1, we fail.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001360 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 cricket::AudioSendParameters parameters;
1362 parameters.codecs.push_back(kOpusCodec);
1363 parameters.codecs[0].bitrate = 0;
1364 parameters.codecs[0].channels = 1;
1365 parameters.codecs[0].params["stereo"] = "1";
1366 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001367}
1368
ossu20a4b3f2017-04-27 02:08:52 -07001369// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001370TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001371 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 cricket::AudioSendParameters parameters;
1373 parameters.codecs.push_back(kOpusCodec);
1374 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001375 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001376 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377}
1378
ossu20a4b3f2017-04-27 02:08:52 -07001379// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001380TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001381 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 0;
1385 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001386 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001387 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388}
1389
ossu20a4b3f2017-04-27 02:08:52 -07001390// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001391TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001392 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 cricket::AudioSendParameters parameters;
1394 parameters.codecs.push_back(kOpusCodec);
1395 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001396 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001398 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001399 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001400
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001402 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001403 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001404}
1405
ossu20a4b3f2017-04-27 02:08:52 -07001406// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001408 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 cricket::AudioSendParameters parameters;
1410 parameters.codecs.push_back(kOpusCodec);
1411 parameters.codecs[0].bitrate = 0;
1412 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001414 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
ossu20a4b3f2017-04-27 02:08:52 -07001417// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001423 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001427
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001430 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001431}
1432
ossu20a4b3f2017-04-27 02:08:52 -07001433// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kOpusCodec);
1438 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1441 EXPECT_EQ(111, spec.payload_type);
1442 EXPECT_EQ(96000, spec.target_bitrate_bps);
1443 EXPECT_EQ("opus", spec.format.name);
1444 EXPECT_EQ(2, spec.format.num_channels);
1445 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
ossu20a4b3f2017-04-27 02:08:52 -07001448// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].bitrate = 30000;
1454 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001455 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001456 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457}
1458
ossu20a4b3f2017-04-27 02:08:52 -07001459// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001461 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 cricket::AudioSendParameters parameters;
1463 parameters.codecs.push_back(kOpusCodec);
1464 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001465 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001466 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467}
1468
ossu20a4b3f2017-04-27 02:08:52 -07001469// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 30000;
1475 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001478}
1479
stefan13f1a0a2016-11-30 07:22:58 -08001480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1481 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1482 200000);
1483}
1484
1485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1486 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1487}
1488
1489TEST_F(WebRtcVoiceEngineTestFake,
1490 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1491 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1492}
1493
1494TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1495 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1496}
1497
1498TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001499 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001500 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1501 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001502 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001503 SetSendParameters(send_parameters_);
1504 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1505 << "Setting max bitrate should keep previous min bitrate.";
1506 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1507 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001508 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001509}
1510
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001511// Test that we can enable NACK with opus as caller.
1512TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001513 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001514 cricket::AudioSendParameters parameters;
1515 parameters.codecs.push_back(kOpusCodec);
1516 parameters.codecs[0].AddFeedbackParam(
1517 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1518 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001519 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001520 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522}
1523
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001524// Test that we can enable NACK with opus as callee.
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001526 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 cricket::AudioSendParameters parameters;
1528 parameters.codecs.push_back(kOpusCodec);
1529 parameters.codecs[0].AddFeedbackParam(
1530 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1531 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001532 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001534 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001535 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001536
1537 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001538 cricket::StreamParams::CreateLegacy(kSsrcX)));
1539 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001540}
1541
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542// Test that we can enable NACK on receive streams.
1543TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001544 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001545 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].AddFeedbackParam(
1549 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1550 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1552 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1555 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556}
1557
1558// Test that we can disable NACK.
1559TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001560 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001561 cricket::AudioSendParameters parameters;
1562 parameters.codecs.push_back(kOpusCodec);
1563 parameters.codecs[0].AddFeedbackParam(
1564 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1565 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001566 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001567 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001568
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 parameters.codecs.clear();
1570 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001571 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573}
1574
1575// Test that we can disable NACK on receive streams.
1576TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001577 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001578 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001579 cricket::AudioSendParameters parameters;
1580 parameters.codecs.push_back(kOpusCodec);
1581 parameters.codecs[0].AddFeedbackParam(
1582 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1583 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001584 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1586 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 parameters.codecs.clear();
1589 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1592 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
1595// Test that NACK is enabled on a new receive stream.
1596TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kIsacCodec);
1600 parameters.codecs.push_back(kCn16000Codec);
1601 parameters.codecs[0].AddFeedbackParam(
1602 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1603 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001605 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
solenberg2100c0b2017-03-01 11:29:29 -08001607 EXPECT_TRUE(AddRecvStream(kSsrcY));
1608 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1609 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1610 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611}
1612
stefanba4c0e42016-02-04 04:12:24 -08001613TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001614 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001615 cricket::AudioSendParameters send_parameters;
1616 send_parameters.codecs.push_back(kOpusCodec);
1617 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001618 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001619
1620 cricket::AudioRecvParameters recv_parameters;
1621 recv_parameters.codecs.push_back(kIsacCodec);
1622 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_TRUE(AddRecvStream(kSsrcX));
1624 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001625 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001626 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001627
ossudedfd282016-06-14 07:12:39 -07001628 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001630 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001631 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001632 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001633}
1634
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001635// Test that we can switch back and forth between Opus and ISAC with CN.
1636TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001637 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001638
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001639 cricket::AudioSendParameters opus_parameters;
1640 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001641 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001642 {
ossu20a4b3f2017-04-27 02:08:52 -07001643 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1644 EXPECT_EQ(111, spec.payload_type);
1645 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001646 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001647
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001648 cricket::AudioSendParameters isac_parameters;
1649 isac_parameters.codecs.push_back(kIsacCodec);
1650 isac_parameters.codecs.push_back(kCn16000Codec);
1651 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001652 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001653 {
ossu20a4b3f2017-04-27 02:08:52 -07001654 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1655 EXPECT_EQ(103, spec.payload_type);
1656 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001657 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001658
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001660 {
ossu20a4b3f2017-04-27 02:08:52 -07001661 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1662 EXPECT_EQ(111, spec.payload_type);
1663 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001664 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665}
1666
1667// Test that we handle various ways of specifying bitrate.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001669 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001670 cricket::AudioSendParameters parameters;
1671 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(103, spec.payload_type);
1676 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1677 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001678 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001682 {
ossu20a4b3f2017-04-27 02:08:52 -07001683 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1684 EXPECT_EQ(103, spec.payload_type);
1685 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1686 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001687 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001689 SetSendParameters(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(103, spec.payload_type);
1693 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1694 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001695 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001697 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001699 {
ossu20a4b3f2017-04-27 02:08:52 -07001700 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1701 EXPECT_EQ(0, spec.payload_type);
1702 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1703 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001704 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001706 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001708 {
ossu20a4b3f2017-04-27 02:08:52 -07001709 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1710 EXPECT_EQ(0, spec.payload_type);
1711 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1712 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001713 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001715 parameters.codecs[0] = kOpusCodec;
1716 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001717 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001718 {
ossu20a4b3f2017-04-27 02:08:52 -07001719 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1720 EXPECT_EQ(111, spec.payload_type);
1721 EXPECT_STREQ("opus", spec.format.name.c_str());
1722 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001723 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724}
1725
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001726// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001729 cricket::AudioSendParameters parameters;
1730 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001731}
1732
1733// Test that we can set send codecs even with telephone-event codec as the first
1734// one on the list.
1735TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001736 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001738 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 parameters.codecs.push_back(kIsacCodec);
1740 parameters.codecs.push_back(kPcmuCodec);
1741 parameters.codecs[0].id = 98; // DTMF
1742 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001744 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1745 EXPECT_EQ(96, spec.payload_type);
1746 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001747 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001748}
1749
solenberg31642aa2016-03-14 08:00:37 -07001750// Test that payload type range is limited for telephone-event codec.
1751TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001752 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001753 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001754 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001755 parameters.codecs.push_back(kIsacCodec);
1756 parameters.codecs[0].id = 0; // DTMF
1757 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001758 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001759 EXPECT_TRUE(channel_->CanInsertDtmf());
1760 parameters.codecs[0].id = 128; // DTMF
1761 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1762 EXPECT_FALSE(channel_->CanInsertDtmf());
1763 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001765 EXPECT_TRUE(channel_->CanInsertDtmf());
1766 parameters.codecs[0].id = -1; // DTMF
1767 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1768 EXPECT_FALSE(channel_->CanInsertDtmf());
1769}
1770
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001771// Test that we can set send codecs even with CN codec as the first
1772// one on the list.
1773TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001774 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 cricket::AudioSendParameters parameters;
1776 parameters.codecs.push_back(kCn16000Codec);
1777 parameters.codecs.push_back(kIsacCodec);
1778 parameters.codecs.push_back(kPcmuCodec);
1779 parameters.codecs[0].id = 98; // wideband CN
1780 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001782 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1783 EXPECT_EQ(96, send_codec_spec.payload_type);
1784 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001785 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786}
1787
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001788// Test that we set VAD and DTMF types correctly as caller.
1789TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001790 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 cricket::AudioSendParameters parameters;
1792 parameters.codecs.push_back(kIsacCodec);
1793 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001794 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs.push_back(kCn16000Codec);
1796 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001797 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001798 parameters.codecs[0].id = 96;
1799 parameters.codecs[2].id = 97; // wideband CN
1800 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001801 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_EQ(96, send_codec_spec.payload_type);
1804 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1805 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001806 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001807 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808}
1809
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001810// Test that we set VAD and DTMF types correctly as callee.
1811TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 cricket::AudioSendParameters parameters;
1814 parameters.codecs.push_back(kIsacCodec);
1815 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001816 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001817 parameters.codecs.push_back(kCn16000Codec);
1818 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001819 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001820 parameters.codecs[0].id = 96;
1821 parameters.codecs[2].id = 97; // wideband CN
1822 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001823 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001824 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001825 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001826
ossu20a4b3f2017-04-27 02:08:52 -07001827 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1828 EXPECT_EQ(96, send_codec_spec.payload_type);
1829 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1830 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001831 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001832 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001833}
1834
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835// Test that we only apply VAD if we have a CN codec that matches the
1836// send codec clockrate.
1837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 parameters.codecs.push_back(kIsacCodec);
1842 parameters.codecs.push_back(kCn16000Codec);
1843 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001845 {
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1848 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001849 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001850 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001851 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001854 {
ossu20a4b3f2017-04-27 02:08:52 -07001855 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1856 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001857 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001858 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001861 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001862 {
ossu20a4b3f2017-04-27 02:08:52 -07001863 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1864 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1865 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001866 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001867 }
Brave Yao5225dd82015-03-26 07:39:19 +08001868 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001870 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001871 {
ossu20a4b3f2017-04-27 02:08:52 -07001872 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1873 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001874 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001875 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876}
1877
1878// Test that we perform case-insensitive matching of codec names.
1879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 cricket::AudioSendParameters parameters;
1882 parameters.codecs.push_back(kIsacCodec);
1883 parameters.codecs.push_back(kPcmuCodec);
1884 parameters.codecs.push_back(kCn16000Codec);
1885 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001886 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 parameters.codecs[0].name = "iSaC";
1888 parameters.codecs[0].id = 96;
1889 parameters.codecs[2].id = 97; // wideband CN
1890 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001892 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1893 EXPECT_EQ(96, send_codec_spec.payload_type);
1894 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1895 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001897 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001898}
1899
stefanba4c0e42016-02-04 04:12:24 -08001900class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1901 public:
1902 WebRtcVoiceEngineWithSendSideBweTest()
1903 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1904};
1905
1906TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1907 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001908 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001909 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001910 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1911 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1912 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001913 extension.id);
1914 return;
1915 }
1916 }
1917 FAIL() << "Transport sequence number extension not in header-extension list.";
1918}
1919
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001920// Test support for audio level header extension.
1921TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001922 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001923}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001924TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001925 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001926}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001927
solenbergd4adce42016-11-17 06:26:52 -08001928// Test support for transport sequence number header extension.
1929TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1930 TestSetSendRtpHeaderExtensions(
1931 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001932}
solenbergd4adce42016-11-17 06:26:52 -08001933TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1934 TestSetRecvRtpHeaderExtensions(
1935 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001936}
1937
solenberg1ac56142015-10-13 03:58:19 -07001938// Test that we can create a channel and start sending on it.
1939TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001940 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(send_parameters_);
1942 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001943 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001944 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001945 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001946}
1947
1948// Test that a channel will send if and only if it has a source and is enabled
1949// for sending.
1950TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001951 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001952 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001953 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001954 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001955 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1956 SetAudioSend(kSsrcX, true, &fake_source_);
1957 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1958 SetAudioSend(kSsrcX, true, nullptr);
1959 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001960}
1961
solenberg94218532016-06-16 10:53:22 -07001962// Test that a channel is muted/unmuted.
1963TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1964 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001965 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001966 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1967 SetAudioSend(kSsrcX, true, nullptr);
1968 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1969 SetAudioSend(kSsrcX, false, nullptr);
1970 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001971}
1972
solenberg6d6e7c52016-04-13 09:07:30 -07001973// Test that SetSendParameters() does not alter a stream's send state.
1974TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1975 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001977
1978 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001979 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001980 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001981
1982 // Changing RTP header extensions will recreate the AudioSendStream.
1983 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001984 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001987
1988 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001989 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001990 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001991
1992 // Changing RTP header extensions will recreate the AudioSendStream.
1993 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001994 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996}
1997
solenberg1ac56142015-10-13 03:58:19 -07001998// Test that we can create a channel and start playing out on it.
1999TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002000 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002001 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002002 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002003 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002004 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002006}
2007
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002008// Test that we can add and remove send streams.
2009TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2010 SetupForMultiSendStream();
2011
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002012 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002013 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014
solenbergc96df772015-10-21 13:01:53 -07002015 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002016 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002017 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002018 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002020 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 }
tfarina5237aaf2015-11-10 23:44:30 -08002022 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023
solenbergc96df772015-10-21 13:01:53 -07002024 // Delete the send streams.
2025 for (uint32_t ssrc : kSsrcs4) {
2026 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002027 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002028 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029 }
solenbergc96df772015-10-21 13:01:53 -07002030 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031}
2032
2033// Test SetSendCodecs correctly configure the codecs in all send streams.
2034TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2035 SetupForMultiSendStream();
2036
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002038 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002040 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041 }
2042
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002043 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002045 parameters.codecs.push_back(kIsacCodec);
2046 parameters.codecs.push_back(kCn16000Codec);
2047 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002048 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049
2050 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002051 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002052 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2053 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002054 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2055 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2056 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002057 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 }
2059
minyue7a973442016-10-20 03:27:12 -07002060 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002061 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002063 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002064 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2065 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002066 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2067 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002068 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 }
2070}
2071
2072// Test we can SetSend on all send streams correctly.
2073TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2074 SetupForMultiSendStream();
2075
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002076 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002077 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002078 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002079 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002080 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002081 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002082 }
2083
2084 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002085 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002086 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002088 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
2090
2091 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002092 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002093 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002095 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 }
2097}
2098
2099// Test we can set the correct statistics on all send streams.
2100TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2101 SetupForMultiSendStream();
2102
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002104 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002106 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 }
solenberg85a04962015-10-27 03:35:21 -07002108
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002109 // Create a receive stream to check that none of the send streams end up in
2110 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002111 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002112
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002114 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002115 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002116 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117
solenberg85a04962015-10-27 03:35:21 -07002118 // Check stats for the added streams.
2119 {
2120 cricket::VoiceMediaInfo info;
2121 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122
solenberg85a04962015-10-27 03:35:21 -07002123 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002124 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002125 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002126 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002127 }
hbos1acfbd22016-11-17 23:43:29 -08002128 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002129
2130 // We have added one receive stream. We should see empty stats.
2131 EXPECT_EQ(info.receivers.size(), 1u);
2132 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 }
solenberg1ac56142015-10-13 03:58:19 -07002134
solenberg2100c0b2017-03-01 11:29:29 -08002135 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002136 {
2137 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002138 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002139 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002140 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002141 EXPECT_EQ(0u, info.receivers.size());
2142 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002143
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002144 // Deliver a new packet - a default receive stream should be created and we
2145 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002146 {
2147 cricket::VoiceMediaInfo info;
2148 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2149 SetAudioReceiveStreamStats();
2150 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002151 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002152 EXPECT_EQ(1u, info.receivers.size());
2153 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002154 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002155 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002156}
2157
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002158// Test that we can add and remove receive streams, and do proper send/playout.
2159// We can receive on multiple streams while sending one stream.
2160TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002161 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002162
solenberg1ac56142015-10-13 03:58:19 -07002163 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002164 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002165 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166
solenberg1ac56142015-10-13 03:58:19 -07002167 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002169 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002170 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171
solenberg1ac56142015-10-13 03:58:19 -07002172 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002173 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002174
2175 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002176 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2177 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2178 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002179
2180 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002181 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183
2184 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002185 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002186 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2187 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188
aleloi84ef6152016-08-04 05:28:21 -07002189 // Restart playout and make sure recv streams are played out.
2190 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002191 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2192 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
aleloi84ef6152016-08-04 05:28:21 -07002194 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002195 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2196 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002197}
2198
wu@webrtc.org97077a32013-10-25 21:18:33 +00002199TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002200 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002201 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2202 .Times(1)
2203 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002204 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2205 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002206 send_parameters_.options.tx_agc_target_dbov = 3;
2207 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2208 send_parameters_.options.tx_agc_limiter = true;
2209 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002210 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2211 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2212 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002213 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002214}
2215
minyue6b825df2016-10-31 04:08:32 -07002216TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2217 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002218 send_parameters_.options.audio_network_adaptor = true;
2219 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002220 SetSendParameters(send_parameters_);
2221 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002222 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002223}
2224
2225TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2226 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002227 send_parameters_.options.audio_network_adaptor = true;
2228 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002229 SetSendParameters(send_parameters_);
2230 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002231 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002232 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002233 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002234 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002235 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002236}
2237
2238TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2239 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002240 send_parameters_.options.audio_network_adaptor = true;
2241 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002242 SetSendParameters(send_parameters_);
2243 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002244 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002245 const int initial_num = call_.GetNumCreatedSendStreams();
2246 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002247 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002248 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2249 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002250 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002251 // AudioSendStream not expected to be recreated.
2252 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2253 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002254 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002255}
2256
michaelt6672b262017-01-11 10:17:59 -08002257class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2258 : public WebRtcVoiceEngineTestFake {
2259 public:
2260 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2261 : WebRtcVoiceEngineTestFake(
2262 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2263 "Enabled/") {}
2264};
2265
2266TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2267 EXPECT_TRUE(SetupSendStream());
2268 cricket::AudioSendParameters parameters;
2269 parameters.codecs.push_back(kOpusCodec);
2270 SetSendParameters(parameters);
2271 const int initial_num = call_.GetNumCreatedSendStreams();
2272 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2273
2274 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2275 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002276 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2277 constexpr int kMinOverheadBps =
2278 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002279
2280 constexpr int kOpusMinBitrateBps = 6000;
2281 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002282 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002283 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002284 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002285 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002286
Oskar Sundbom78807582017-11-16 11:09:55 +01002287 parameters.options.audio_network_adaptor = true;
2288 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002289 SetSendParameters(parameters);
2290
ossu11bfc532017-02-16 05:37:06 -08002291 constexpr int kMinOverheadWithAnaBps =
2292 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002293
2294 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002295 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002296
minyuececec102017-03-27 13:04:25 -07002297 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002298 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002299}
2300
minyuececec102017-03-27 13:04:25 -07002301// This test is similar to
2302// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2303// additional field trial.
2304TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2305 SetRtpSendParameterUpdatesMaxBitrate) {
2306 EXPECT_TRUE(SetupSendStream());
2307 cricket::AudioSendParameters send_parameters;
2308 send_parameters.codecs.push_back(kOpusCodec);
2309 SetSendParameters(send_parameters);
2310
2311 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2312 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2313 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2314
2315 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002316 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002317 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2318
2319 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2320#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2321 constexpr int kMinOverhead = 3333;
2322#else
2323 constexpr int kMinOverhead = 6666;
2324#endif
2325 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2326}
2327
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002328// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002329// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002330TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002331 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002332 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002333}
2334
2335TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2336 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002337 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002338 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002339 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002340 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002341 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002342 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002343 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002344
solenberg85a04962015-10-27 03:35:21 -07002345 // Check stats for the added streams.
2346 {
2347 cricket::VoiceMediaInfo info;
2348 EXPECT_EQ(true, channel_->GetStats(&info));
2349
2350 // We have added one send stream. We should see the stats we've set.
2351 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002352 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002353 // We have added one receive stream. We should see empty stats.
2354 EXPECT_EQ(info.receivers.size(), 1u);
2355 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2356 }
solenberg1ac56142015-10-13 03:58:19 -07002357
solenberg566ef242015-11-06 15:34:49 -08002358 // Start sending - this affects some reported stats.
2359 {
2360 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002361 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002362 EXPECT_EQ(true, channel_->GetStats(&info));
2363 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002364 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002365 }
2366
solenberg2100c0b2017-03-01 11:29:29 -08002367 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002368 {
2369 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002370 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002371 EXPECT_EQ(true, channel_->GetStats(&info));
2372 EXPECT_EQ(1u, info.senders.size());
2373 EXPECT_EQ(0u, info.receivers.size());
2374 }
solenberg1ac56142015-10-13 03:58:19 -07002375
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002376 // Deliver a new packet - a default receive stream should be created and we
2377 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002378 {
2379 cricket::VoiceMediaInfo info;
2380 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2381 SetAudioReceiveStreamStats();
2382 EXPECT_EQ(true, channel_->GetStats(&info));
2383 EXPECT_EQ(1u, info.senders.size());
2384 EXPECT_EQ(1u, info.receivers.size());
2385 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002386 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002387 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388}
2389
2390// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002391// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002392TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002393 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002394 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2395 EXPECT_TRUE(AddRecvStream(kSsrcY));
2396 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397}
2398
2399// Test that the local SSRC is the same on sending and receiving channels if the
2400// receive channel is created before the send channel.
2401TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002402 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002403 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002404 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002405 cricket::StreamParams::CreateLegacy(kSsrcX)));
2406 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2407 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002408}
2409
2410// Test that we can properly receive packets.
2411TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002412 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002413 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002414 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002415
2416 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2417 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420// Test that we can properly receive packets on multiple streams.
2421TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002423 const uint32_t ssrc1 = 1;
2424 const uint32_t ssrc2 = 2;
2425 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002426 EXPECT_TRUE(AddRecvStream(ssrc1));
2427 EXPECT_TRUE(AddRecvStream(ssrc2));
2428 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002430 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002431 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002432 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002433 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434 }
mflodman3d7db262016-04-29 00:57:13 -07002435
2436 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2437 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2438 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2439
2440 EXPECT_EQ(s1.received_packets(), 0);
2441 EXPECT_EQ(s2.received_packets(), 0);
2442 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002443
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002445 EXPECT_EQ(s1.received_packets(), 0);
2446 EXPECT_EQ(s2.received_packets(), 0);
2447 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002448
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002450 EXPECT_EQ(s1.received_packets(), 1);
2451 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2452 EXPECT_EQ(s2.received_packets(), 0);
2453 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002454
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002456 EXPECT_EQ(s1.received_packets(), 1);
2457 EXPECT_EQ(s2.received_packets(), 1);
2458 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2459 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002460
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002462 EXPECT_EQ(s1.received_packets(), 1);
2463 EXPECT_EQ(s2.received_packets(), 1);
2464 EXPECT_EQ(s3.received_packets(), 1);
2465 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002466
mflodman3d7db262016-04-29 00:57:13 -07002467 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2468 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2469 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470}
2471
solenberg2100c0b2017-03-01 11:29:29 -08002472// Test that receiving on an unsignaled stream works (a stream is created).
2473TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002474 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002475 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2476
solenberg7e63ef02015-11-20 00:19:43 -08002477 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002478
2479 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002480 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2481 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002482}
2483
solenberg2100c0b2017-03-01 11:29:29 -08002484// Test that receiving N unsignaled stream works (streams will be created), and
2485// that packets are forwarded to them all.
2486TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002487 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002488 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002489 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2490
solenberg2100c0b2017-03-01 11:29:29 -08002491 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002492 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002493 rtc::SetBE32(&packet[8], ssrc);
2494 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002495
solenberg2100c0b2017-03-01 11:29:29 -08002496 // Verify we have one new stream for each loop iteration.
2497 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002498 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2499 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002500 }
mflodman3d7db262016-04-29 00:57:13 -07002501
solenberg2100c0b2017-03-01 11:29:29 -08002502 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002503 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002504 rtc::SetBE32(&packet[8], ssrc);
2505 DeliverPacket(packet, sizeof(packet));
2506
solenbergebb349d2017-03-13 05:46:15 -07002507 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002508 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2509 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2510 }
2511
2512 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2513 constexpr uint32_t kAnotherSsrc = 667;
2514 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002515 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002516
2517 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002518 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002519 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002520 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2522 EXPECT_EQ(2, streams[i]->received_packets());
2523 }
2524 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2525 EXPECT_EQ(1, streams[i]->received_packets());
2526 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002527 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002528}
2529
solenberg2100c0b2017-03-01 11:29:29 -08002530// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002531// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002532TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002533 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002534 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002535 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2536
2537 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002538 const uint32_t signaled_ssrc = 1;
2539 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002540 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002541 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002542 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2543 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002544 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002545
2546 // Note that the first unknown SSRC cannot be 0, because we only support
2547 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002548 const uint32_t unsignaled_ssrc = 7011;
2549 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002550 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002551 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2552 packet, sizeof(packet)));
2553 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2554
2555 DeliverPacket(packet, sizeof(packet));
2556 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2557
2558 rtc::SetBE32(&packet[8], signaled_ssrc);
2559 DeliverPacket(packet, sizeof(packet));
2560 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2561 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002562}
2563
solenberg4904fb62017-02-17 12:01:14 -08002564// Two tests to verify that adding a receive stream with the same SSRC as a
2565// previously added unsignaled stream will only recreate underlying stream
2566// objects if the stream parameters have changed.
2567TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2568 EXPECT_TRUE(SetupChannel());
2569
2570 // Spawn unsignaled stream with SSRC=1.
2571 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2572 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2573 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2574 sizeof(kPcmuFrame)));
2575
2576 // Verify that the underlying stream object in Call is not recreated when a
2577 // stream with SSRC=1 is added.
2578 const auto& streams = call_.GetAudioReceiveStreams();
2579 EXPECT_EQ(1, streams.size());
2580 int audio_receive_stream_id = streams.front()->id();
2581 EXPECT_TRUE(AddRecvStream(1));
2582 EXPECT_EQ(1, streams.size());
2583 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2584}
2585
2586TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2587 EXPECT_TRUE(SetupChannel());
2588
2589 // Spawn unsignaled stream with SSRC=1.
2590 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2591 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2592 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2593 sizeof(kPcmuFrame)));
2594
2595 // Verify that the underlying stream object in Call *is* recreated when a
2596 // stream with SSRC=1 is added, and which has changed stream parameters.
2597 const auto& streams = call_.GetAudioReceiveStreams();
2598 EXPECT_EQ(1, streams.size());
2599 int audio_receive_stream_id = streams.front()->id();
2600 cricket::StreamParams stream_params;
2601 stream_params.ssrcs.push_back(1);
2602 stream_params.sync_label = "sync_label";
2603 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2604 EXPECT_EQ(1, streams.size());
2605 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2606}
2607
solenberg0a617e22015-10-20 15:49:38 -07002608// Test that we properly handle failures to add a receive stream.
2609TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002610 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002611 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002612 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613}
2614
solenberg0a617e22015-10-20 15:49:38 -07002615// Test that we properly handle failures to add a send stream.
2616TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002617 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002618 voe_.set_fail_create_channel(true);
2619 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2620}
2621
solenberg1ac56142015-10-13 03:58:19 -07002622// Test that AddRecvStream creates new stream.
2623TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002624 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002625 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002626 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002627 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002628}
2629
2630// Test that after adding a recv stream, we do not decode more codecs than
2631// those previously passed into SetRecvCodecs.
2632TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002633 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002634 cricket::AudioRecvParameters parameters;
2635 parameters.codecs.push_back(kIsacCodec);
2636 parameters.codecs.push_back(kPcmuCodec);
2637 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002638 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002639 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2640 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2641 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642}
2643
2644// Test that we properly clean up any streams that were added, even if
2645// not explicitly removed.
2646TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002648 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002649 EXPECT_TRUE(AddRecvStream(1));
2650 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2652 delete channel_;
2653 channel_ = NULL;
2654 EXPECT_EQ(0, voe_.GetNumChannels());
2655}
2656
wu@webrtc.org78187522013-10-07 23:32:02 +00002657TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002658 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002659 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002660}
2661
2662TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002664 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002665 // Manually delete channel to simulate a failure.
2666 int channel = voe_.GetLastChannel();
2667 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2668 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002669 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002670 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002671 EXPECT_NE(channel, new_channel);
2672 // The last created channel is deleted too.
2673 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002674}
2675
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002676// Test the InsertDtmf on default send stream as caller.
2677TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002678 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002679}
2680
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002681// Test the InsertDtmf on default send stream as callee
2682TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002683 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002684}
2685
2686// Test the InsertDtmf on specified send stream as caller.
2687TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002688 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002689}
2690
2691// Test the InsertDtmf on specified send stream as callee.
2692TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002693 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002694}
2695
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002696TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002697 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002698 EXPECT_CALL(adm_,
2699 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2700 EXPECT_CALL(adm_,
2701 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2702 EXPECT_CALL(adm_,
2703 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002704
solenberg246b8172015-12-08 09:50:23 -08002705 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2706 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002707
solenberg246b8172015-12-08 09:50:23 -08002708 // Nothing set in AudioOptions, so everything should be as default.
2709 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002710 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002711 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002712 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2713 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714
2715 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002716 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2717 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002718 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002719 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720
2721 // Turn echo cancellation back on, with settings, and make sure
2722 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002723 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2724 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002725 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002726 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002728 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2729 // control.
solenberg76377c52017-02-21 00:54:31 -08002730 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2731 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002732 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002733 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002734
2735 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002736 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2737 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002738 send_parameters_.options.delay_agnostic_aec = false;
2739 send_parameters_.options.extended_filter_aec = false;
2740 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002741 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002742
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002743 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002744 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2745 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002746 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002747 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002748
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002750 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2751 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002752 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002753 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002754 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002755 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002756
2757 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002758 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2759 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002760 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002761 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002762 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002763 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002765 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002766 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2767 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002768 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002770 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002773 send_parameters_.options.noise_suppression = false;
2774 send_parameters_.options.highpass_filter = false;
2775 send_parameters_.options.typing_detection = false;
2776 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002777 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002778 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002779
solenberg1ac56142015-10-13 03:58:19 -07002780 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002781 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002783 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002784 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002785 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002786 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2787 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002788 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789}
2790
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002792 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002793 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002794 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002795 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002796 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002797 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002798 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002799 EXPECT_CALL(adm_,
2800 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2801 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2802 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002803 webrtc::AudioProcessing::Config apm_config;
2804 EXPECT_CALL(*apm_, GetConfig())
2805 .Times(10)
2806 .WillRepeatedly(ReturnPointee(&apm_config));
2807 EXPECT_CALL(*apm_, ApplyConfig(_))
2808 .Times(10)
2809 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002810 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002811
kwiberg686a8ef2016-02-26 03:00:35 -08002812 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002813 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002814 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002815 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002816 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002817 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818
2819 // Have to add a stream to make SetSend work.
2820 cricket::StreamParams stream1;
2821 stream1.ssrcs.push_back(1);
2822 channel1->AddSendStream(stream1);
2823 cricket::StreamParams stream2;
2824 stream2.ssrcs.push_back(2);
2825 channel2->AddSendStream(stream2);
2826
2827 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002828 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002829 parameters_options_all.options.echo_cancellation = true;
2830 parameters_options_all.options.auto_gain_control = true;
2831 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002832 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2833 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002834 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002835 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002836 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002837 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002838 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002839 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002840 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002841 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002842
2843 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002844 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002845 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002846 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2847 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002848 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002849 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002850 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002851 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002852 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002853 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002854 expected_options.echo_cancellation = true;
2855 expected_options.auto_gain_control = true;
2856 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002857 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858
2859 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002860 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002861 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002862 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2863 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002864 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002865 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002866 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002867 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002868 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002869 expected_options.echo_cancellation = true;
2870 expected_options.auto_gain_control = false;
2871 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002872 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002873
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002876 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002877 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002878 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002879 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002880 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
solenberg76377c52017-02-21 00:54:31 -08002882 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2883 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002884 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002886 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002888 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002892 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002893 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002894 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002896 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002897
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002899 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2900 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002901 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2902 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002903 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2904 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002905 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002907 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002908 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002909 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002910 expected_options.echo_cancellation = true;
2911 expected_options.auto_gain_control = false;
2912 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002913 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914}
2915
wu@webrtc.orgde305012013-10-31 15:40:38 +00002916// This test verifies DSCP settings are properly applied on voice media channel.
2917TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002918 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002919 cricket::FakeNetworkInterface network_interface;
2920 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002921 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002922
peahb1c9d1d2017-07-25 15:45:24 -07002923 webrtc::AudioProcessing::Config apm_config;
2924 EXPECT_CALL(*apm_, GetConfig())
2925 .Times(3)
2926 .WillRepeatedly(ReturnPointee(&apm_config));
2927 EXPECT_CALL(*apm_, ApplyConfig(_))
2928 .Times(3)
2929 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002930 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002931
solenbergbc37fc82016-04-04 09:54:44 -07002932 channel.reset(
2933 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002934 channel->SetInterface(&network_interface);
2935 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2936 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2937
2938 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002939 channel.reset(
2940 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002941 channel->SetInterface(&network_interface);
2942 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2943
2944 // Verify that setting the option to false resets the
2945 // DiffServCodePoint.
2946 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002947 channel.reset(
2948 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002949 channel->SetInterface(&network_interface);
2950 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2951 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2952
2953 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002954}
2955
solenberg1ac56142015-10-13 03:58:19 -07002956TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002958 cricket::WebRtcVoiceMediaChannel* media_channel =
2959 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002960 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002961 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002962 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002963 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2964 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2965 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002966 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002967 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968}
2969
solenberg1ac56142015-10-13 03:58:19 -07002970TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002971 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002973 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2974 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2975 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002976 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002977 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002978 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2979 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002980 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002981 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002982 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002983 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984}
2985
solenberg4bac9c52015-10-09 02:32:53 -07002986TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002987 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002988 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002990 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002992 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2993 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2994 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002995}
2996
solenberg2100c0b2017-03-01 11:29:29 -08002997TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002998 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002999
3000 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003001 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3003
3004 // Should remember the volume "2" which will be set on new unsignaled streams,
3005 // and also set the gain to 2 on existing unsignaled streams.
3006 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3007 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3008
3009 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3010 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3011 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3012 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3013 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3014 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3015
3016 // Setting gain with SSRC=0 should affect all unsignaled streams.
3017 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003018 if (kMaxUnsignaledRecvStreams > 1) {
3019 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3020 }
solenberg2100c0b2017-03-01 11:29:29 -08003021 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3022
3023 // Setting gain on an individual stream affects only that.
3024 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003025 if (kMaxUnsignaledRecvStreams > 1) {
3026 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3027 }
solenberg2100c0b2017-03-01 11:29:29 -08003028 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029}
3030
pbos8fc7fa72015-07-15 08:02:58 -07003031TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003032 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003033 const std::string kSyncLabel = "AvSyncLabel";
3034
solenbergff976312016-03-30 23:28:51 -07003035 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003036 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3037 sp.sync_label = kSyncLabel;
3038 // Creating two channels to make sure that sync label is set properly for both
3039 // the default voice channel and following ones.
3040 EXPECT_TRUE(channel_->AddRecvStream(sp));
3041 sp.ssrcs[0] += 1;
3042 EXPECT_TRUE(channel_->AddRecvStream(sp));
3043
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003044 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003045 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003046 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003047 << "SyncGroup should be set based on sync_label";
3048 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003049 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003050 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003051}
3052
solenberg3a941542015-11-16 07:34:50 -08003053// TODO(solenberg): Remove, once recv streams are configured through Call.
3054// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003055TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003056 // Test that setting the header extensions results in the expected state
3057 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003058 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003059 ssrcs.push_back(223);
3060 ssrcs.push_back(224);
3061
solenbergff976312016-03-30 23:28:51 -07003062 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003063 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003064 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003065 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003066 cricket::StreamParams::CreateLegacy(ssrc)));
3067 }
3068
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003069 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003070 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003071 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003072 EXPECT_NE(nullptr, s);
3073 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3074 }
3075
3076 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003077 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003078 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003079 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003080 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003081 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003082 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003084 EXPECT_NE(nullptr, s);
3085 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003086 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3087 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003088 for (const auto& s_ext : s_exts) {
3089 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003090 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 }
3092 }
3093 }
3094 }
3095
3096 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003097 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003098 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003099 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 EXPECT_NE(nullptr, s);
3101 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3102 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003103}
3104
3105TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3106 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003107 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003108 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109 static const unsigned char kRtcp[] = {
3110 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3111 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3114 };
jbaucheec21bd2016-03-20 06:15:43 -07003115 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003116
solenbergff976312016-03-30 23:28:51 -07003117 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003118 cricket::WebRtcVoiceMediaChannel* media_channel =
3119 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003120 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003121 EXPECT_TRUE(media_channel->AddRecvStream(
3122 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3123
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003124 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003126 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 EXPECT_EQ(0, s->received_packets());
3128 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3129 EXPECT_EQ(1, s->received_packets());
3130 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3131 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003132}
Minyue2013aec2015-05-13 14:14:42 +02003133
solenberg0a617e22015-10-20 15:49:38 -07003134// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003135// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003136TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003137 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003138 EXPECT_TRUE(AddRecvStream(kSsrcY));
3139 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003140 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003141 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3142 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3143 EXPECT_TRUE(AddRecvStream(kSsrcW));
3144 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003145}
3146
solenberg7602aab2016-11-14 11:30:07 -08003147TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3148 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003149 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003150 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003151 cricket::StreamParams::CreateLegacy(kSsrcY)));
3152 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3153 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3154 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003155 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003156 cricket::StreamParams::CreateLegacy(kSsrcW)));
3157 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3158 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003159}
stefan658910c2015-09-03 05:48:32 -07003160
deadbeef884f5852016-01-15 09:20:04 -08003161TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003162 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003163 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3164 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003165
3166 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003167 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3168 EXPECT_TRUE(AddRecvStream(kSsrcX));
3169 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003170
3171 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003172 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3173 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003174
3175 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003176 channel_->SetRawAudioSink(kSsrcX, nullptr);
3177 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003178}
3179
solenberg2100c0b2017-03-01 11:29:29 -08003180TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003181 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003182 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3183 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003184 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3185 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003186
3187 // Should be able to set a default sink even when no stream exists.
3188 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3189
solenberg2100c0b2017-03-01 11:29:29 -08003190 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3191 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003192 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003193 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003194
3195 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003196 channel_->SetRawAudioSink(kSsrc0, nullptr);
3197 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003198
3199 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003200 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3201 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003202
3203 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003204 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003205 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003206 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3207
3208 // Spawn another unsignaled stream - it should be assigned the default sink
3209 // and the previous unsignaled stream should lose it.
3210 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3211 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3212 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3213 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003214 if (kMaxUnsignaledRecvStreams > 1) {
3215 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3216 }
solenberg2100c0b2017-03-01 11:29:29 -08003217 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3218
3219 // Reset the default sink - the second unsignaled stream should lose it.
3220 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003221 if (kMaxUnsignaledRecvStreams > 1) {
3222 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3223 }
solenberg2100c0b2017-03-01 11:29:29 -08003224 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3225
3226 // Try setting the default sink while two streams exists.
3227 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3230 }
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3232
3233 // Try setting the sink for the first unsignaled stream using its known SSRC.
3234 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3237 }
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003239 if (kMaxUnsignaledRecvStreams > 1) {
3240 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3241 }
deadbeef884f5852016-01-15 09:20:04 -08003242}
3243
skvlad7a43d252016-03-22 15:32:27 -07003244// Test that, just like the video channel, the voice channel communicates the
3245// network state to the call.
3246TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003247 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003248
3249 EXPECT_EQ(webrtc::kNetworkUp,
3250 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3251 EXPECT_EQ(webrtc::kNetworkUp,
3252 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3253
3254 channel_->OnReadyToSend(false);
3255 EXPECT_EQ(webrtc::kNetworkDown,
3256 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3257 EXPECT_EQ(webrtc::kNetworkUp,
3258 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3259
3260 channel_->OnReadyToSend(true);
3261 EXPECT_EQ(webrtc::kNetworkUp,
3262 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3263 EXPECT_EQ(webrtc::kNetworkUp,
3264 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3265}
3266
aleloi18e0b672016-10-04 02:45:47 -07003267// Test that playout is still started after changing parameters
3268TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3269 SetupRecvStream();
3270 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003271 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003272
3273 // Changing RTP header extensions will recreate the AudioReceiveStream.
3274 cricket::AudioRecvParameters parameters;
3275 parameters.extensions.push_back(
3276 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3277 channel_->SetRecvParameters(parameters);
3278
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003280}
3281
Zhi Huangfa266ef2017-12-13 10:27:46 -08003282// Tests when GetSources is called with non-existing ssrc, it will return an
3283// empty list of RtpSource without crashing.
3284TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3285 // Setup an recv stream with |kSsrcX|.
3286 SetupRecvStream();
3287 cricket::WebRtcVoiceMediaChannel* media_channel =
3288 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3289 // Call GetSources with |kSsrcY| which doesn't exist.
3290 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3291 EXPECT_EQ(0u, sources.size());
3292}
3293
stefan658910c2015-09-03 05:48:32 -07003294// Tests that the library initializes and shuts down properly.
3295TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003296 // If the VoiceEngine wants to gather available codecs early, that's fine but
3297 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003298 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003299 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3300 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003301 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003302 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003303 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003304 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003305 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003306 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003307 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003308 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3309 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003310 EXPECT_TRUE(channel != nullptr);
3311 delete channel;
solenbergff976312016-03-30 23:28:51 -07003312}
stefan658910c2015-09-03 05:48:32 -07003313
solenbergff976312016-03-30 23:28:51 -07003314// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003315TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3316 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg2a877972017-12-15 16:42:15 +01003317 EXPECT_CALL(adm, AddRef()).Times(5);
Niels Möller6f72f562017-10-19 13:15:17 +02003318 EXPECT_CALL(adm, Release())
Fredrik Solenberg2a877972017-12-15 16:42:15 +01003319 .Times(5)
Niels Möller6f72f562017-10-19 13:15:17 +02003320 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003321 {
peaha9cc40b2017-06-29 08:32:09 -07003322 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3323 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003324 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003325 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003326 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003327 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003328 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003329 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003330 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003331 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3332 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3333 EXPECT_TRUE(channel != nullptr);
3334 delete channel;
3335 }
stefan658910c2015-09-03 05:48:32 -07003336}
3337
ossu20a4b3f2017-04-27 02:08:52 -07003338// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3339TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003340 // TODO(ossu): Why are the payload types of codecs with non-static payload
3341 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003342 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003343 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3344 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003345 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003346 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003347 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003348 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003349 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003350 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3351 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3352 (clockrate == 0 || codec.clockrate == clockrate);
3353 };
3354 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003355 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003356 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003358 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003359 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003360 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003361 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003362 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003363 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003364 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003365 EXPECT_EQ(126, codec.id);
3366 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3367 // Remove these checks once both send and receive side assigns payload types
3368 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003369 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003370 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003373 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003374 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003375 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003376 EXPECT_EQ(111, codec.id);
3377 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3378 EXPECT_EQ("10", codec.params.find("minptime")->second);
3379 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3380 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003381 }
3382 }
stefan658910c2015-09-03 05:48:32 -07003383}
3384
3385// Tests that VoE supports at least 32 channels
3386TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003387 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003388 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3389 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003390 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003391 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003392 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003393 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003394 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003395 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003396 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003397
3398 cricket::VoiceMediaChannel* channels[32];
3399 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003400 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003401 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3402 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003403 if (!channel)
3404 break;
stefan658910c2015-09-03 05:48:32 -07003405 channels[num_channels++] = channel;
3406 }
3407
tfarina5237aaf2015-11-10 23:44:30 -08003408 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003409 EXPECT_EQ(expected, num_channels);
3410
3411 while (num_channels > 0) {
3412 delete channels[--num_channels];
3413 }
stefan658910c2015-09-03 05:48:32 -07003414}
3415
3416// Test that we set our preferred codecs properly.
3417TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003418 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3419 // - Check that our builtin codecs are usable by Channel.
3420 // - The codecs provided by the engine is usable by Channel.
3421 // It does not check that the codecs in the RecvParameters are actually
3422 // what we sent in - though it's probably reasonable to expect so, if
3423 // SetRecvParameters returns true.
3424 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003425 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003426 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3427 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003428 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003429 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003430 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003431 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003432 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003433 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003434 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003435 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3436 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003437 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003438 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003439 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003440}
ossu9def8002017-02-09 05:14:32 -08003441
3442TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3443 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003444 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3445 {48000, 2, 16000, 10000, 20000}};
3446 spec1.info.allow_comfort_noise = false;
3447 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003448 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003449 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3450 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003451 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003452 specs.push_back(webrtc::AudioCodecSpec{
3453 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3454 {16000, 1, 13300}});
3455 specs.push_back(
3456 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3457 specs.push_back(
3458 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003459
ossueb1fde42017-05-02 06:46:30 -07003460 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3461 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3462 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003463 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003464 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003465 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003466 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003467
peaha9cc40b2017-06-29 08:32:09 -07003468 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3469 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003470 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003471 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003472 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003473 auto codecs = engine.recv_codecs();
3474 EXPECT_EQ(11, codecs.size());
3475
3476 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3477 // check the actual values safely, to provide better test results.
3478 auto get_codec =
3479 [&codecs](size_t index) -> const cricket::AudioCodec& {
3480 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3481 if (codecs.size() > index)
3482 return codecs[index];
3483 return missing_codec;
3484 };
3485
3486 // Ensure the general codecs are generated first and in order.
3487 for (size_t i = 0; i != specs.size(); ++i) {
3488 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3489 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3490 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3491 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3492 }
3493
3494 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003495 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003496 auto find_codec =
3497 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3498 for (size_t i = 0; i != codecs.size(); ++i) {
3499 const cricket::AudioCodec& codec = codecs[i];
3500 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3501 codec.clockrate == format.clockrate_hz &&
3502 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003503 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003504 }
3505 }
3506 return -1;
3507 };
3508
3509 // Ensure all supplementary codecs are generated last. Their internal ordering
3510 // is not important.
3511 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3512 const int num_specs = static_cast<int>(specs.size());
3513 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3514 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3515 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3516 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3517 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3518 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3519 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3520}