blob: 4fd087ac1a399e8f51abbe49556a91b7647dc92a [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"
36#include "voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
46
solenberg418b7d32017-06-13 00:38:27 -070047constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070048
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
50const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070051const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
53const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
55const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080056const cricket::AudioCodec
57 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
58const cricket::AudioCodec
59 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
60
solenberg2100c0b2017-03-01 11:29:29 -080061const uint32_t kSsrc0 = 0;
62const uint32_t kSsrc1 = 1;
63const uint32_t kSsrcX = 0x99;
64const uint32_t kSsrcY = 0x17;
65const uint32_t kSsrcZ = 0x42;
66const uint32_t kSsrcW = 0x02;
67const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
solenberg971cab02016-06-14 10:02:41 -070069constexpr int kRtpHistoryMs = 5000;
70
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010071constexpr webrtc::GainControl::Mode kDefaultAgcMode =
72#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
73 webrtc::GainControl::kFixedDigital;
74#else
75 webrtc::GainControl::kAdaptiveAnalog;
76#endif
77
78constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
79 webrtc::NoiseSuppression::kHigh;
80
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081class FakeVoEWrapper : public cricket::VoEWrapper {
82 public:
83 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070084 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085 }
86};
skvlad11a9cbf2016-10-07 11:53:05 -070087
solenberg76377c52017-02-21 00:54:31 -080088class MockTransmitMixer : public webrtc::voe::TransmitMixer {
89 public:
90 MockTransmitMixer() = default;
91 virtual ~MockTransmitMixer() = default;
92
93 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
94};
solenberg9a5f032222017-03-15 06:14:12 -070095
96void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
97 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010098
99 // Setup.
Niels Möller6f72f562017-10-19 13:15:17 +0200100 EXPECT_CALL(*adm, AddRef()).Times(1);
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100101 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700102#if defined(WEBRTC_WIN)
103 EXPECT_CALL(*adm, SetPlayoutDevice(
104 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
105 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
106 .WillOnce(Return(0));
107#else
108 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
109#endif // #if defined(WEBRTC_WIN)
110 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
111 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
112 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100113#if defined(WEBRTC_WIN)
114 EXPECT_CALL(*adm, SetRecordingDevice(
115 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
116 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
117 .WillOnce(Return(0));
118#else
119 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
120#endif // #if defined(WEBRTC_WIN)
121 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
122 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
123 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700124 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
125 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
126 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100127
128 // Teardown.
129 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
130 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
131 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
132 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
133 EXPECT_CALL(*adm, Release())
134 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700135}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200136} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137
solenbergff976312016-03-30 23:28:51 -0700138// Tests that our stub library "works".
139TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700140 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700141 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700142 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
143 new rtc::RefCountedObject<
144 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700145 webrtc::AudioProcessing::Config apm_config;
146 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
147 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700148 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700149 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800150 StrictMock<MockTransmitMixer> transmit_mixer;
151 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700152 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700153 EXPECT_FALSE(voe.IsInited());
154 {
ossuc54071d2016-08-17 02:45:41 -0700155 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700156 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700157 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700158 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700159 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700160 EXPECT_TRUE(voe.IsInited());
161 }
162 EXPECT_FALSE(voe.IsInited());
163}
164
deadbeef884f5852016-01-15 09:20:04 -0800165class FakeAudioSink : public webrtc::AudioSinkInterface {
166 public:
167 void OnData(const Data& audio) override {}
168};
169
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800170class FakeAudioSource : public cricket::AudioSource {
171 void SetSink(Sink* sink) override {}
172};
173
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174class WebRtcVoiceEngineTestFake : public testing::Test {
175 public:
stefanba4c0e42016-02-04 04:12:24 -0800176 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
177
178 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700179 : apm_(new rtc::RefCountedObject<
180 StrictMock<webrtc::test::MockAudioProcessing>>()),
181 apm_gc_(*apm_->gain_control()),
182 apm_ec_(*apm_->echo_cancellation()),
183 apm_ns_(*apm_->noise_suppression()),
184 apm_vd_(*apm_->voice_detection()),
185 call_(webrtc::Call::Config(&event_log_)),
186 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700187 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800188 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700189 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800190 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700191 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
192 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700193 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700194 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800195 // Default Options.
196 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
197 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100198 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
199 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800200 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100201 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
202 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800203 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
204 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
205 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
206 // Init does not overwrite default AGC config.
207 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
208 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
209 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800210 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
211 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700212 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800213 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700214 // factories. Those tests should probably be moved elsewhere.
215 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
216 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
217 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700218 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700219 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700220 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200221 send_parameters_.codecs.push_back(kPcmuCodec);
222 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100223
solenberg76377c52017-02-21 00:54:31 -0800224 // Default Options.
225 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 }
solenberg8189b022016-06-14 12:13:00 -0700227
solenbergff976312016-03-30 23:28:51 -0700228 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700229 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700230 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
231 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200232 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000233 }
solenberg8189b022016-06-14 12:13:00 -0700234
solenbergff976312016-03-30 23:28:51 -0700235 bool SetupRecvStream() {
236 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700237 return false;
238 }
solenberg2100c0b2017-03-01 11:29:29 -0800239 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700240 }
solenberg8189b022016-06-14 12:13:00 -0700241
solenbergff976312016-03-30 23:28:51 -0700242 bool SetupSendStream() {
243 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000244 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000245 }
solenberg2100c0b2017-03-01 11:29:29 -0800246 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800247 return false;
248 }
peaha9cc40b2017-06-29 08:32:09 -0700249 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800250 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 }
solenberg8189b022016-06-14 12:13:00 -0700252
253 bool AddRecvStream(uint32_t ssrc) {
254 EXPECT_TRUE(channel_);
255 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
256 }
257
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700259 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700260 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800261 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
262 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700263 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800264 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000265 }
solenberg8189b022016-06-14 12:13:00 -0700266
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700268 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000269 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000270 }
solenberg8189b022016-06-14 12:13:00 -0700271
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200272 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 }
275
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100276 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
277 const auto* send_stream = call_.GetAudioSendStream(ssrc);
278 EXPECT_TRUE(send_stream);
279 return *send_stream;
280 }
281
deadbeef884f5852016-01-15 09:20:04 -0800282 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
283 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
284 EXPECT_TRUE(recv_stream);
285 return *recv_stream;
286 }
287
solenberg3a941542015-11-16 07:34:50 -0800288 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800289 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800290 }
291
solenberg7add0582015-11-20 09:59:34 -0800292 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800293 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800294 }
295
solenberg059fb442016-10-26 05:12:24 -0700296 void SetSend(bool enable) {
297 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700298 if (enable) {
299 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
300 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
301 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700302 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700303 }
solenberg059fb442016-10-26 05:12:24 -0700304 channel_->SetSend(enable);
305 }
306
307 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700308 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700309 ASSERT_TRUE(channel_);
310 EXPECT_TRUE(channel_->SetSendParameters(params));
311 }
312
minyue6b825df2016-10-31 04:08:32 -0700313 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
314 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700315 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700316 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700317 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700318 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700319 }
320 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700321 }
322
solenbergffbbcac2016-11-17 05:25:37 -0800323 void TestInsertDtmf(uint32_t ssrc, bool caller,
324 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700325 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000326 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700327 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328 // send stream.
329 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800330 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000332
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700334 SetSendParameters(send_parameters_);
335 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800337 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800338 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700339 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000341
342 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700343 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800344 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000345 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800346 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000347 }
348
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800350 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100352 // Test send.
353 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800354 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100355 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800356 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800357 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800358 EXPECT_EQ(codec.id, telephone_event.payload_type);
359 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100360 EXPECT_EQ(2, telephone_event.event_code);
361 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362 }
363
364 // Test that send bandwidth is set correctly.
365 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000366 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
367 // |expected_result| is the expected result from SetMaxSendBandwidth().
368 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700369 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
370 int max_bitrate,
371 bool expected_result,
372 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200373 cricket::AudioSendParameters parameters;
374 parameters.codecs.push_back(codec);
375 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700376 if (expected_result) {
377 SetSendParameters(parameters);
378 } else {
379 EXPECT_FALSE(channel_->SetSendParameters(parameters));
380 }
solenberg2100c0b2017-03-01 11:29:29 -0800381 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 }
383
skvlade0d46372016-04-07 22:59:22 -0700384 // Sets the per-stream maximum bitrate limit for the specified SSRC.
385 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700386 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700387 EXPECT_EQ(1UL, parameters.encodings.size());
388
Oskar Sundbom78807582017-11-16 11:09:55 +0100389 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700390 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700391 }
392
solenberg059fb442016-10-26 05:12:24 -0700393 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700394 cricket::AudioSendParameters send_parameters;
395 send_parameters.codecs.push_back(codec);
396 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700397 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700398 }
399
ossu20a4b3f2017-04-27 02:08:52 -0700400 void CheckSendCodecBitrate(int32_t ssrc,
401 const char expected_name[],
402 int expected_bitrate) {
403 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
404 EXPECT_EQ(expected_name, spec->format.name);
405 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700406 }
407
ossu20a4b3f2017-04-27 02:08:52 -0700408 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
409 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700410 }
411
minyue6b825df2016-10-31 04:08:32 -0700412 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
413 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
414 }
415
skvlade0d46372016-04-07 22:59:22 -0700416 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
417 int global_max,
418 int stream_max,
419 bool expected_result,
420 int expected_codec_bitrate) {
421 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800422 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700423
424 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700425 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800426 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700427
428 // Verify that reading back the parameters gives results
429 // consistent with the Set() result.
430 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800431 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700432 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
433 EXPECT_EQ(expected_result ? stream_max : -1,
434 resulting_parameters.encodings[0].max_bitrate_bps);
435
436 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800437 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700438 }
439
stefan13f1a0a2016-11-30 07:22:58 -0800440 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
441 int expected_min_bitrate_bps,
442 const char* start_bitrate_kbps,
443 int expected_start_bitrate_bps,
444 const char* max_bitrate_kbps,
445 int expected_max_bitrate_bps) {
446 EXPECT_TRUE(SetupSendStream());
447 auto& codecs = send_parameters_.codecs;
448 codecs.clear();
449 codecs.push_back(kOpusCodec);
450 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
451 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
452 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
453 SetSendParameters(send_parameters_);
454
455 EXPECT_EQ(expected_min_bitrate_bps,
456 call_.GetConfig().bitrate_config.min_bitrate_bps);
457 EXPECT_EQ(expected_start_bitrate_bps,
458 call_.GetConfig().bitrate_config.start_bitrate_bps);
459 EXPECT_EQ(expected_max_bitrate_bps,
460 call_.GetConfig().bitrate_config.max_bitrate_bps);
461 }
462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700464 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000465
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000466 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000468
469 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700470 send_parameters_.extensions.push_back(
471 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700472 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800473 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000474
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000475 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200476 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700477 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800478 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000479
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000480 // Ensure extension is set properly.
481 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700482 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
486 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000487
solenberg7add0582015-11-20 09:59:34 -0800488 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800490 cricket::StreamParams::CreateLegacy(kSsrcY)));
491 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
492 call_.GetAudioSendStream(kSsrcY));
493 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
494 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
495 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496
497 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200498 send_parameters_.codecs.push_back(kPcmuCodec);
499 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700500 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
502 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000503 }
504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700506 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000507
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000508 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000510
511 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700512 recv_parameters_.extensions.push_back(
513 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800514 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000516
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000517 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800518 recv_parameters_.extensions.clear();
519 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000521
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000522 // Ensure extension is set properly.
523 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700524 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800525 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800526 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
527 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
528 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000529
solenberg7add0582015-11-20 09:59:34 -0800530 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800531 EXPECT_TRUE(AddRecvStream(kSsrcY));
532 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
533 call_.GetAudioReceiveStream(kSsrcY));
534 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
535 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
536 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000537
538 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800539 recv_parameters_.extensions.clear();
540 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800541 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
542 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000543 }
544
solenberg85a04962015-10-27 03:35:21 -0700545 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
546 webrtc::AudioSendStream::Stats stats;
547 stats.local_ssrc = 12;
548 stats.bytes_sent = 345;
549 stats.packets_sent = 678;
550 stats.packets_lost = 9012;
551 stats.fraction_lost = 34.56f;
552 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100553 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700554 stats.ext_seqnum = 789;
555 stats.jitter_ms = 12;
556 stats.rtt_ms = 345;
557 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100558 stats.apm_statistics.delay_median_ms = 234;
559 stats.apm_statistics.delay_standard_deviation_ms = 567;
560 stats.apm_statistics.echo_return_loss = 890;
561 stats.apm_statistics.echo_return_loss_enhancement = 1234;
562 stats.apm_statistics.residual_echo_likelihood = 0.432f;
563 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100564 stats.ana_statistics.bitrate_action_counter = 321;
565 stats.ana_statistics.channel_action_counter = 432;
566 stats.ana_statistics.dtx_action_counter = 543;
567 stats.ana_statistics.fec_action_counter = 654;
568 stats.ana_statistics.frame_length_increase_counter = 765;
569 stats.ana_statistics.frame_length_decrease_counter = 876;
570 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700571 stats.typing_noise_detected = true;
572 return stats;
573 }
574 void SetAudioSendStreamStats() {
575 for (auto* s : call_.GetAudioSendStreams()) {
576 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200577 }
solenberg85a04962015-10-27 03:35:21 -0700578 }
solenberg566ef242015-11-06 15:34:49 -0800579 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
580 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700581 const auto stats = GetAudioSendStreamStats();
582 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
583 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
584 EXPECT_EQ(info.packets_sent, stats.packets_sent);
585 EXPECT_EQ(info.packets_lost, stats.packets_lost);
586 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
587 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800588 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700589 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
590 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
591 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
592 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100593 EXPECT_EQ(info.apm_statistics.delay_median_ms,
594 stats.apm_statistics.delay_median_ms);
595 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
596 stats.apm_statistics.delay_standard_deviation_ms);
597 EXPECT_EQ(info.apm_statistics.echo_return_loss,
598 stats.apm_statistics.echo_return_loss);
599 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
600 stats.apm_statistics.echo_return_loss_enhancement);
601 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
602 stats.apm_statistics.residual_echo_likelihood);
603 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
604 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700605 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
606 stats.ana_statistics.bitrate_action_counter);
607 EXPECT_EQ(info.ana_statistics.channel_action_counter,
608 stats.ana_statistics.channel_action_counter);
609 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
610 stats.ana_statistics.dtx_action_counter);
611 EXPECT_EQ(info.ana_statistics.fec_action_counter,
612 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700613 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
614 stats.ana_statistics.frame_length_increase_counter);
615 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
616 stats.ana_statistics.frame_length_decrease_counter);
617 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
618 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800619 EXPECT_EQ(info.typing_noise_detected,
620 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700621 }
622
623 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
624 webrtc::AudioReceiveStream::Stats stats;
625 stats.remote_ssrc = 123;
626 stats.bytes_rcvd = 456;
627 stats.packets_rcvd = 768;
628 stats.packets_lost = 101;
629 stats.fraction_lost = 23.45f;
630 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100631 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700632 stats.ext_seqnum = 678;
633 stats.jitter_ms = 901;
634 stats.jitter_buffer_ms = 234;
635 stats.jitter_buffer_preferred_ms = 567;
636 stats.delay_estimate_ms = 890;
637 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700638 stats.total_samples_received = 5678901;
639 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200640 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200641 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700642 stats.expand_rate = 5.67f;
643 stats.speech_expand_rate = 8.90f;
644 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200645 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700646 stats.accelerate_rate = 4.56f;
647 stats.preemptive_expand_rate = 7.89f;
648 stats.decoding_calls_to_silence_generator = 12;
649 stats.decoding_calls_to_neteq = 345;
650 stats.decoding_normal = 67890;
651 stats.decoding_plc = 1234;
652 stats.decoding_cng = 5678;
653 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700654 stats.decoding_muted_output = 3456;
655 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200656 return stats;
657 }
658 void SetAudioReceiveStreamStats() {
659 for (auto* s : call_.GetAudioReceiveStreams()) {
660 s->SetStats(GetAudioReceiveStreamStats());
661 }
662 }
663 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700664 const auto stats = GetAudioReceiveStreamStats();
665 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
666 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
667 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
668 EXPECT_EQ(info.packets_lost, stats.packets_lost);
669 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
670 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800671 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700672 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
673 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
674 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200675 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700676 stats.jitter_buffer_preferred_ms);
677 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
678 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700679 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
680 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200681 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200682 EXPECT_EQ(info.jitter_buffer_delay_seconds,
683 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700684 EXPECT_EQ(info.expand_rate, stats.expand_rate);
685 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
686 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200687 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700688 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
689 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200690 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700691 stats.decoding_calls_to_silence_generator);
692 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
693 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
694 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
695 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
696 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700697 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700698 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200699 }
hbos1acfbd22016-11-17 23:43:29 -0800700 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
701 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
702 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
703 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
704 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
705 codec.ToCodecParameters());
706 }
707 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
708 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
709 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
710 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
711 codec.ToCodecParameters());
712 }
713 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200714
peah8271d042016-11-22 07:24:52 -0800715 bool IsHighPassFilterEnabled() {
716 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
717 }
718
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700720 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700721 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800722 webrtc::test::MockGainControl& apm_gc_;
723 webrtc::test::MockEchoCancellation& apm_ec_;
724 webrtc::test::MockNoiseSuppression& apm_ns_;
725 webrtc::test::MockVoiceDetection& apm_vd_;
726 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700727 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200728 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700730 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700731 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200732 cricket::AudioSendParameters send_parameters_;
733 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800734 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700735 webrtc::AudioProcessing::Config apm_config_;
736
stefanba4c0e42016-02-04 04:12:24 -0800737 private:
738 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000739};
740
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741// Tests that we can create and destroy a channel.
742TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700743 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744}
745
solenberg31fec402016-05-06 02:13:12 -0700746// Test that we can add a send stream and that it has the correct defaults.
747TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
748 EXPECT_TRUE(SetupChannel());
749 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800750 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
751 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
752 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700753 EXPECT_EQ("", config.rtp.c_name);
754 EXPECT_EQ(0u, config.rtp.extensions.size());
755 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
756 config.send_transport);
757}
758
759// Test that we can add a receive stream and that it has the correct defaults.
760TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
761 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800762 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700763 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800764 GetRecvStreamConfig(kSsrcX);
765 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700766 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
767 EXPECT_FALSE(config.rtp.transport_cc);
768 EXPECT_EQ(0u, config.rtp.extensions.size());
769 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
770 config.rtcp_send_transport);
771 EXPECT_EQ("", config.sync_group);
772}
773
stefanba4c0e42016-02-04 04:12:24 -0800774TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700775 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800776 bool opus_found = false;
777 for (cricket::AudioCodec codec : codecs) {
778 if (codec.name == "opus") {
779 EXPECT_TRUE(HasTransportCc(codec));
780 opus_found = true;
781 }
782 }
783 EXPECT_TRUE(opus_found);
784}
785
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786// Test that we set our inbound codecs properly, including changing PT.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
791 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800792 parameters.codecs.push_back(kTelephoneEventCodec1);
793 parameters.codecs.push_back(kTelephoneEventCodec2);
794 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 parameters.codecs[2].id = 126;
796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700798 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
799 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
800 {{0, {"PCMU", 8000, 1}},
801 {106, {"ISAC", 16000, 1}},
802 {126, {"telephone-event", 8000, 1}},
803 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that we fail to set an unknown inbound codec.
807TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
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);
deadbeef67cf2c12016-04-13 10:07:16 -0700811 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813}
814
815// Test that we fail if we have duplicate types in the inbound list.
816TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 cricket::AudioRecvParameters parameters;
819 parameters.codecs.push_back(kIsacCodec);
820 parameters.codecs.push_back(kCn16000Codec);
821 parameters.codecs[1].id = kIsacCodec.id;
822 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that we can decode OPUS without stereo parameters.
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
830 parameters.codecs.push_back(kPcmuCodec);
831 parameters.codecs.push_back(kOpusCodec);
832 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800833 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700834 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
835 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
836 {{0, {"PCMU", 8000, 1}},
837 {103, {"ISAC", 16000, 1}},
838 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that we can decode OPUS with stereo = 0.
842TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 cricket::AudioRecvParameters parameters;
845 parameters.codecs.push_back(kIsacCodec);
846 parameters.codecs.push_back(kPcmuCodec);
847 parameters.codecs.push_back(kOpusCodec);
848 parameters.codecs[2].params["stereo"] = "0";
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800850 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700851 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
852 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
853 {{0, {"PCMU", 8000, 1}},
854 {103, {"ISAC", 16000, 1}},
855 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we can decode OPUS with stereo = 1.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kPcmuCodec);
864 parameters.codecs.push_back(kOpusCodec);
865 parameters.codecs[2].params["stereo"] = "1";
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800867 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700868 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {103, {"ISAC", 16000, 1}},
872 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000873}
874
875// Test that changes to recv codecs are applied to all streams.
876TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700877 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs.push_back(kTelephoneEventCodec1);
882 parameters.codecs.push_back(kTelephoneEventCodec2);
883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 parameters.codecs[2].id = 126;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700886 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
887 EXPECT_TRUE(AddRecvStream(ssrc));
888 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
889 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
890 {{0, {"PCMU", 8000, 1}},
891 {106, {"ISAC", 16000, 1}},
892 {126, {"telephone-event", 8000, 1}},
893 {107, {"telephone-event", 32000, 1}}})));
894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895}
896
897TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700898 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 cricket::AudioRecvParameters parameters;
900 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800901 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
solenberg2100c0b2017-03-01 11:29:29 -0800904 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800905 ASSERT_EQ(1, dm.count(106));
906 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907}
908
909// Test that we can apply the same set of codecs again while playing.
910TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700911 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 cricket::AudioRecvParameters parameters;
913 parameters.codecs.push_back(kIsacCodec);
914 parameters.codecs.push_back(kCn16000Codec);
915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700916 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
deadbeefcb383672017-04-26 16:28:42 -0700919 // Remapping a payload type to a different codec should fail.
920 parameters.codecs[0] = kOpusCodec;
921 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
926// Test that we can add a codec while playing.
927TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700928 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 parameters.codecs.push_back(kCn16000Codec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700933 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200935 parameters.codecs.push_back(kOpusCodec);
936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800937 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
deadbeefcb383672017-04-26 16:28:42 -0700940// Test that we accept adding the same codec with a different payload type.
941// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
942TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
943 EXPECT_TRUE(SetupRecvStream());
944 cricket::AudioRecvParameters parameters;
945 parameters.codecs.push_back(kIsacCodec);
946 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
947
948 ++parameters.codecs[0].id;
949 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
950}
951
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700953 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955 // Test that when autobw is enabled, bitrate is kept as the default
956 // value. autobw is enabled for the following tests because the target
957 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
959 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
962 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
ossu20a4b3f2017-04-27 02:08:52 -0700965 // opus, default bitrate == 32000 in mono.
966 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700973 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
974 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700975 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700978 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
979 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
980 // Rates above the max (510000) should be capped.
981 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982}
983
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700985 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000986
987 // Test that we can only set a maximum bitrate for a fixed-rate codec
988 // if it's bigger than the fixed rate.
989
990 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700991 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
995 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
996 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998}
999
1000TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001001 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001002 const int kDesiredBitrate = 128000;
1003 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001004 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001005 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001007
1008 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001009 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001010
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001012}
1013
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014// Test that bitrate cannot be set for CBR codecs.
1015// Bitrate is ignored if it is higher than the fixed bitrate.
1016// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001017TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001018 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
1020 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001021 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001022 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001023
1024 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001025 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001026 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001027
1028 send_parameters_.max_bandwidth_bps = 128;
1029 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001030 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031}
1032
skvlade0d46372016-04-07 22:59:22 -07001033// Test that the per-stream bitrate limit and the global
1034// bitrate limit both apply.
1035TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1036 EXPECT_TRUE(SetupSendStream());
1037
ossu20a4b3f2017-04-27 02:08:52 -07001038 // opus, default bitrate == 32000.
1039 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001040 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1041 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1042 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1043
1044 // CBR codecs allow both maximums to exceed the bitrate.
1045 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1046 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1047 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1049
1050 // CBR codecs don't allow per stream maximums to be too low.
1051 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1053}
1054
1055// Test that an attempt to set RtpParameters for a stream that does not exist
1056// fails.
1057TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1058 EXPECT_TRUE(SetupChannel());
1059 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001060 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001061 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1062
1063 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001065}
1066
1067TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001068 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001069 // This test verifies that setting RtpParameters succeeds only if
1070 // the structure contains exactly one encoding.
1071 // TODO(skvlad): Update this test when we start supporting setting parameters
1072 // for each encoding individually.
1073
1074 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001075 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001076 // Two or more encodings should result in failure.
1077 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001079 // Zero encodings should also fail.
1080 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001081 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001082}
1083
1084// Changing the SSRC through RtpParameters is not allowed.
1085TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1086 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001087 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001088 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001089 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001090}
1091
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001093// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1095 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001096 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001097 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001099 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001100 ASSERT_EQ(1u, parameters.encodings.size());
1101 ASSERT_TRUE(parameters.encodings[0].active);
1102 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1104 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105
1106 // Now change it back to active and verify we resume sending.
1107 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1109 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001110}
1111
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112// Test that SetRtpSendParameters configures the correct encoding channel for
1113// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001114TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1115 SetupForMultiSendStream();
1116 // Create send streams.
1117 for (uint32_t ssrc : kSsrcs4) {
1118 EXPECT_TRUE(
1119 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1120 }
1121 // Configure one stream to be limited by the stream config, another to be
1122 // limited by the global max, and the third one with no per-stream limit
1123 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001124 SetGlobalMaxBitrate(kOpusCodec, 32000);
1125 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1128
ossu20a4b3f2017-04-27 02:08:52 -07001129 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1130 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1131 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001132
1133 // Remove the global cap; the streams should switch to their respective
1134 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001135 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001136 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1137 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1138 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001139}
1140
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001141// Test that GetRtpSendParameters returns the currently configured codecs.
1142TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143 EXPECT_TRUE(SetupSendStream());
1144 cricket::AudioSendParameters parameters;
1145 parameters.codecs.push_back(kIsacCodec);
1146 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001147 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148
solenberg2100c0b2017-03-01 11:29:29 -08001149 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1152 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001153}
1154
deadbeefcb443432016-12-12 11:12:36 -08001155// Test that GetRtpSendParameters returns an SSRC.
1156TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1157 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001158 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001159 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001160 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001161}
1162
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001163// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165 EXPECT_TRUE(SetupSendStream());
1166 cricket::AudioSendParameters parameters;
1167 parameters.codecs.push_back(kIsacCodec);
1168 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001169 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170
solenberg2100c0b2017-03-01 11:29:29 -08001171 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001172
1173 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001174 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001176 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001177 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1178 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001179}
1180
minyuececec102017-03-27 13:04:25 -07001181// Test that max_bitrate_bps in send stream config gets updated correctly when
1182// SetRtpSendParameters is called.
1183TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1184 webrtc::test::ScopedFieldTrials override_field_trials(
1185 "WebRTC-Audio-SendSideBwe/Enabled/");
1186 EXPECT_TRUE(SetupSendStream());
1187 cricket::AudioSendParameters send_parameters;
1188 send_parameters.codecs.push_back(kOpusCodec);
1189 SetSendParameters(send_parameters);
1190
1191 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1192 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1193 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1194
1195 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001196 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001197 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1198
1199 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1200 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1201}
1202
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001203// Test that GetRtpReceiveParameters returns the currently configured codecs.
1204TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1205 EXPECT_TRUE(SetupRecvStream());
1206 cricket::AudioRecvParameters parameters;
1207 parameters.codecs.push_back(kIsacCodec);
1208 parameters.codecs.push_back(kPcmuCodec);
1209 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1210
1211 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001212 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1214 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1215 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1216}
1217
deadbeefcb443432016-12-12 11:12:36 -08001218// Test that GetRtpReceiveParameters returns an SSRC.
1219TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1220 EXPECT_TRUE(SetupRecvStream());
1221 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001222 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001223 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001224 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001225}
1226
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001227// Test that if we set/get parameters multiple times, we get the same results.
1228TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1229 EXPECT_TRUE(SetupRecvStream());
1230 cricket::AudioRecvParameters parameters;
1231 parameters.codecs.push_back(kIsacCodec);
1232 parameters.codecs.push_back(kPcmuCodec);
1233 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1234
1235 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001236 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001237
1238 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001239 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001240
1241 // ... And this shouldn't change the params returned by
1242 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001243 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1244 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001245}
1246
deadbeef3bc15102017-04-20 19:25:07 -07001247// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1248// aren't signaled. It should return an empty "RtpEncodingParameters" when
1249// configured to receive an unsignaled stream and no packets have been received
1250// yet, and start returning the SSRC once a packet has been received.
1251TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1252 ASSERT_TRUE(SetupChannel());
1253 // Call necessary methods to configure receiving a default stream as
1254 // soon as it arrives.
1255 cricket::AudioRecvParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
1258 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1259
1260 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1261 // stream. Should return nothing.
1262 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1263
1264 // Set a sink for an unsignaled stream.
1265 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1266 // Value of "0" means "unsignaled stream".
1267 channel_->SetRawAudioSink(0, std::move(fake_sink));
1268
1269 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1270 // in this method means "unsignaled stream".
1271 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1272 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1273 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1274
1275 // Receive PCMU packet (SSRC=1).
1276 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1277
1278 // The |ssrc| member should still be unset.
1279 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1280 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1281 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1282}
1283
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284// Test that we apply codecs properly.
1285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001286 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001287 cricket::AudioSendParameters parameters;
1288 parameters.codecs.push_back(kIsacCodec);
1289 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001290 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001291 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001292 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001293 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001294 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1295 EXPECT_EQ(96, send_codec_spec.payload_type);
1296 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1297 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1298 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001299 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001300 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
ossu20a4b3f2017-04-27 02:08:52 -07001303// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1304// AudioSendStream.
1305TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001306 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 cricket::AudioSendParameters parameters;
1308 parameters.codecs.push_back(kIsacCodec);
1309 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001310 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 parameters.codecs[0].id = 96;
1312 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001313 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001314 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001315 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001316 // Calling SetSendCodec again with same codec which is already set.
1317 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001318 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001319 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001320}
1321
ossu20a4b3f2017-04-27 02:08:52 -07001322// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1323// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001324
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001325// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001327 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 cricket::AudioSendParameters parameters;
1329 parameters.codecs.push_back(kOpusCodec);
1330 parameters.codecs[0].bitrate = 0;
1331 parameters.codecs[0].clockrate = 50000;
1332 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001335// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].channels = 0;
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001345// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
1351 parameters.codecs[0].channels = 0;
1352 parameters.codecs[0].params["stereo"] = "1";
1353 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
1356// Test that if channel is 1 for opus and there's no stereo, we fail.
1357TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001358 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 cricket::AudioSendParameters parameters;
1360 parameters.codecs.push_back(kOpusCodec);
1361 parameters.codecs[0].bitrate = 0;
1362 parameters.codecs[0].channels = 1;
1363 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001364}
1365
1366// Test that if channel is 1 for opus and stereo=0, we fail.
1367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001368 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 cricket::AudioSendParameters parameters;
1370 parameters.codecs.push_back(kOpusCodec);
1371 parameters.codecs[0].bitrate = 0;
1372 parameters.codecs[0].channels = 1;
1373 parameters.codecs[0].params["stereo"] = "0";
1374 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375}
1376
1377// Test that if channel is 1 for opus and stereo=1, we fail.
1378TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001379 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 cricket::AudioSendParameters parameters;
1381 parameters.codecs.push_back(kOpusCodec);
1382 parameters.codecs[0].bitrate = 0;
1383 parameters.codecs[0].channels = 1;
1384 parameters.codecs[0].params["stereo"] = "1";
1385 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386}
1387
ossu20a4b3f2017-04-27 02:08:52 -07001388// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001390 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 cricket::AudioSendParameters parameters;
1392 parameters.codecs.push_back(kOpusCodec);
1393 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001394 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001395 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396}
1397
ossu20a4b3f2017-04-27 02:08:52 -07001398// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].bitrate = 0;
1404 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407}
1408
ossu20a4b3f2017-04-27 02:08:52 -07001409// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001415 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001418 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001419
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423}
1424
ossu20a4b3f2017-04-27 02:08:52 -07001425// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 0;
1431 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434}
1435
ossu20a4b3f2017-04-27 02:08:52 -07001436// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001442 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001446
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001448 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001449 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001450}
1451
ossu20a4b3f2017-04-27 02:08:52 -07001452// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001454 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 cricket::AudioSendParameters parameters;
1456 parameters.codecs.push_back(kOpusCodec);
1457 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001458 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001459 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1460 EXPECT_EQ(111, spec.payload_type);
1461 EXPECT_EQ(96000, spec.target_bitrate_bps);
1462 EXPECT_EQ("opus", spec.format.name);
1463 EXPECT_EQ(2, spec.format.num_channels);
1464 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465}
1466
ossu20a4b3f2017-04-27 02:08:52 -07001467// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].bitrate = 30000;
1473 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001474 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001475 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476}
1477
ossu20a4b3f2017-04-27 02:08:52 -07001478// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001484 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001485 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001486}
1487
ossu20a4b3f2017-04-27 02:08:52 -07001488// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001489TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001490 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001491 cricket::AudioSendParameters parameters;
1492 parameters.codecs.push_back(kOpusCodec);
1493 parameters.codecs[0].bitrate = 30000;
1494 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001495 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001496 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001497}
1498
stefan13f1a0a2016-11-30 07:22:58 -08001499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1500 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1501 200000);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1505 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1506}
1507
1508TEST_F(WebRtcVoiceEngineTestFake,
1509 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1510 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1511}
1512
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1514 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1515}
1516
1517TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001518 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001519 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1520 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001521 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001522 SetSendParameters(send_parameters_);
1523 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1524 << "Setting max bitrate should keep previous min bitrate.";
1525 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1526 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001527 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001528}
1529
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001530// Test that we can enable NACK with opus as caller.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541}
1542
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001543// Test that we can enable NACK with opus as callee.
1544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupRecvStream());
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, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001553 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001555
1556 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001557 cricket::StreamParams::CreateLegacy(kSsrcX)));
1558 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001559}
1560
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561// Test that we can enable NACK on receive streams.
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001565 cricket::AudioSendParameters parameters;
1566 parameters.codecs.push_back(kOpusCodec);
1567 parameters.codecs[0].AddFeedbackParam(
1568 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1569 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001570 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1571 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1574 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575}
1576
1577// Test that we can disable NACK.
1578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].AddFeedbackParam(
1583 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1584 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001585 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001586 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).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);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
1594// Test that we can disable NACK on receive streams.
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].AddFeedbackParam(
1601 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1602 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 parameters.codecs.clear();
1608 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1611 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
1614// Test that NACK is enabled on a new receive stream.
1615TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 cricket::AudioSendParameters parameters;
1618 parameters.codecs.push_back(kIsacCodec);
1619 parameters.codecs.push_back(kCn16000Codec);
1620 parameters.codecs[0].AddFeedbackParam(
1621 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1622 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001625
solenberg2100c0b2017-03-01 11:29:29 -08001626 EXPECT_TRUE(AddRecvStream(kSsrcY));
1627 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1628 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1629 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001630}
1631
stefanba4c0e42016-02-04 04:12:24 -08001632TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001633 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001634 cricket::AudioSendParameters send_parameters;
1635 send_parameters.codecs.push_back(kOpusCodec);
1636 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001638
1639 cricket::AudioRecvParameters recv_parameters;
1640 recv_parameters.codecs.push_back(kIsacCodec);
1641 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_TRUE(AddRecvStream(kSsrcX));
1643 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001644 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001645 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001646
ossudedfd282016-06-14 07:12:39 -07001647 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001649 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001650 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001651 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001652}
1653
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001654// Test that we can switch back and forth between Opus and ISAC with CN.
1655TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001656 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001657
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters opus_parameters;
1659 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001661 {
ossu20a4b3f2017-04-27 02:08:52 -07001662 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1663 EXPECT_EQ(111, spec.payload_type);
1664 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001665 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 cricket::AudioSendParameters isac_parameters;
1668 isac_parameters.codecs.push_back(kIsacCodec);
1669 isac_parameters.codecs.push_back(kCn16000Codec);
1670 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001672 {
ossu20a4b3f2017-04-27 02:08:52 -07001673 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1674 EXPECT_EQ(103, spec.payload_type);
1675 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001676 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001679 {
ossu20a4b3f2017-04-27 02:08:52 -07001680 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1681 EXPECT_EQ(111, spec.payload_type);
1682 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684}
1685
1686// Test that we handle various ways of specifying bitrate.
1687TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(103, spec.payload_type);
1695 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1696 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001697 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001700 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001701 {
ossu20a4b3f2017-04-27 02:08:52 -07001702 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1703 EXPECT_EQ(103, spec.payload_type);
1704 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1705 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001706 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001707 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001708 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001709 {
ossu20a4b3f2017-04-27 02:08:52 -07001710 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1711 EXPECT_EQ(103, spec.payload_type);
1712 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1713 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001714 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001716 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
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(0, spec.payload_type);
1721 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1722 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001723 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001725 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001727 {
ossu20a4b3f2017-04-27 02:08:52 -07001728 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1729 EXPECT_EQ(0, spec.payload_type);
1730 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1731 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001732 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001733
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 parameters.codecs[0] = kOpusCodec;
1735 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001736 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001737 {
ossu20a4b3f2017-04-27 02:08:52 -07001738 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1739 EXPECT_EQ(111, spec.payload_type);
1740 EXPECT_STREQ("opus", spec.format.name.c_str());
1741 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001742 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743}
1744
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001745// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001746TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001747 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 cricket::AudioSendParameters parameters;
1749 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001750}
1751
1752// Test that we can set send codecs even with telephone-event codec as the first
1753// one on the list.
1754TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001755 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001757 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 parameters.codecs.push_back(kIsacCodec);
1759 parameters.codecs.push_back(kPcmuCodec);
1760 parameters.codecs[0].id = 98; // DTMF
1761 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001763 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1764 EXPECT_EQ(96, spec.payload_type);
1765 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001766 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001767}
1768
solenberg31642aa2016-03-14 08:00:37 -07001769// Test that payload type range is limited for telephone-event codec.
1770TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001771 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001772 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001773 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001774 parameters.codecs.push_back(kIsacCodec);
1775 parameters.codecs[0].id = 0; // DTMF
1776 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001778 EXPECT_TRUE(channel_->CanInsertDtmf());
1779 parameters.codecs[0].id = 128; // DTMF
1780 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1781 EXPECT_FALSE(channel_->CanInsertDtmf());
1782 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001783 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001784 EXPECT_TRUE(channel_->CanInsertDtmf());
1785 parameters.codecs[0].id = -1; // DTMF
1786 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1787 EXPECT_FALSE(channel_->CanInsertDtmf());
1788}
1789
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001790// Test that we can set send codecs even with CN codec as the first
1791// one on the list.
1792TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001793 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001794 cricket::AudioSendParameters parameters;
1795 parameters.codecs.push_back(kCn16000Codec);
1796 parameters.codecs.push_back(kIsacCodec);
1797 parameters.codecs.push_back(kPcmuCodec);
1798 parameters.codecs[0].id = 98; // wideband CN
1799 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001800 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(96, send_codec_spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001804 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805}
1806
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001807// Test that we set VAD and DTMF types correctly as caller.
1808TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001809 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001810 cricket::AudioSendParameters parameters;
1811 parameters.codecs.push_back(kIsacCodec);
1812 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 parameters.codecs.push_back(kCn16000Codec);
1815 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001816 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001817 parameters.codecs[0].id = 96;
1818 parameters.codecs[2].id = 97; // wideband CN
1819 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_EQ(96, send_codec_spec.payload_type);
1823 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1824 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001825 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001826 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827}
1828
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001829// Test that we set VAD and DTMF types correctly as callee.
1830TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001832 cricket::AudioSendParameters parameters;
1833 parameters.codecs.push_back(kIsacCodec);
1834 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001835 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs.push_back(kCn16000Codec);
1837 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001838 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 parameters.codecs[0].id = 96;
1840 parameters.codecs[2].id = 97; // wideband CN
1841 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001842 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001843 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001844 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001845
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_EQ(96, send_codec_spec.payload_type);
1848 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1849 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001850 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001851 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001852}
1853
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854// Test that we only apply VAD if we have a CN codec that matches the
1855// send codec clockrate.
1856TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 parameters.codecs.push_back(kIsacCodec);
1861 parameters.codecs.push_back(kCn16000Codec);
1862 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001864 {
ossu20a4b3f2017-04-27 02:08:52 -07001865 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1866 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1867 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001868 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001869 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001870 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001873 {
ossu20a4b3f2017-04-27 02:08:52 -07001874 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1875 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001876 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001877 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001879 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001881 {
ossu20a4b3f2017-04-27 02:08:52 -07001882 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1883 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1884 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001885 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001886 }
Brave Yao5225dd82015-03-26 07:39:19 +08001887 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001890 {
ossu20a4b3f2017-04-27 02:08:52 -07001891 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1892 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001893 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001895}
1896
1897// Test that we perform case-insensitive matching of codec names.
1898TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001899 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 cricket::AudioSendParameters parameters;
1901 parameters.codecs.push_back(kIsacCodec);
1902 parameters.codecs.push_back(kPcmuCodec);
1903 parameters.codecs.push_back(kCn16000Codec);
1904 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001905 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 parameters.codecs[0].name = "iSaC";
1907 parameters.codecs[0].id = 96;
1908 parameters.codecs[2].id = 97; // wideband CN
1909 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001910 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001911 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1912 EXPECT_EQ(96, send_codec_spec.payload_type);
1913 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1914 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001915 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001916 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917}
1918
stefanba4c0e42016-02-04 04:12:24 -08001919class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1920 public:
1921 WebRtcVoiceEngineWithSendSideBweTest()
1922 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1923};
1924
1925TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1926 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001927 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001928 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001929 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1930 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1931 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001932 extension.id);
1933 return;
1934 }
1935 }
1936 FAIL() << "Transport sequence number extension not in header-extension list.";
1937}
1938
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001939// Test support for audio level header extension.
1940TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001941 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001942}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001943TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001944 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001945}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001946
solenbergd4adce42016-11-17 06:26:52 -08001947// Test support for transport sequence number header extension.
1948TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1949 TestSetSendRtpHeaderExtensions(
1950 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001951}
solenbergd4adce42016-11-17 06:26:52 -08001952TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1953 TestSetRecvRtpHeaderExtensions(
1954 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955}
1956
solenberg1ac56142015-10-13 03:58:19 -07001957// Test that we can create a channel and start sending on it.
1958TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001959 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(send_parameters_);
1961 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001962 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001963 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001964 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001965}
1966
1967// Test that a channel will send if and only if it has a source and is enabled
1968// for sending.
1969TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001972 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001973 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001974 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1975 SetAudioSend(kSsrcX, true, &fake_source_);
1976 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1977 SetAudioSend(kSsrcX, true, nullptr);
1978 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001979}
1980
solenberg94218532016-06-16 10:53:22 -07001981// Test that a channel is muted/unmuted.
1982TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1983 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1986 SetAudioSend(kSsrcX, true, nullptr);
1987 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1988 SetAudioSend(kSsrcX, false, nullptr);
1989 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001990}
1991
solenberg6d6e7c52016-04-13 09:07:30 -07001992// Test that SetSendParameters() does not alter a stream's send state.
1993TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1994 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996
1997 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001998 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001999 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002000
2001 // Changing RTP header extensions will recreate the AudioSendStream.
2002 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002003 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002006
2007 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002008 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002009 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002010
2011 // Changing RTP header extensions will recreate the AudioSendStream.
2012 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002013 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002014 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002015}
2016
solenberg1ac56142015-10-13 03:58:19 -07002017// Test that we can create a channel and start playing out on it.
2018TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002019 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002020 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002021 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002022 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002023 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002024 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002025}
2026
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027// Test that we can add and remove send streams.
2028TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2029 SetupForMultiSendStream();
2030
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002032 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002033
solenbergc96df772015-10-21 13:01:53 -07002034 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002036 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002037 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002039 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 }
tfarina5237aaf2015-11-10 23:44:30 -08002041 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042
solenbergc96df772015-10-21 13:01:53 -07002043 // Delete the send streams.
2044 for (uint32_t ssrc : kSsrcs4) {
2045 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002046 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002047 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 }
solenbergc96df772015-10-21 13:01:53 -07002049 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050}
2051
2052// Test SetSendCodecs correctly configure the codecs in all send streams.
2053TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2054 SetupForMultiSendStream();
2055
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002056 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002057 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002059 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 }
2061
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002062 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002064 parameters.codecs.push_back(kIsacCodec);
2065 parameters.codecs.push_back(kCn16000Codec);
2066 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068
2069 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002070 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002071 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2072 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002073 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2074 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2075 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002076 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002077 }
2078
minyue7a973442016-10-20 03:27:12 -07002079 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002080 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002081 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002082 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002083 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2084 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002085 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2086 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002087 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089}
2090
2091// Test we can SetSend on all send streams correctly.
2092TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2093 SetupForMultiSendStream();
2094
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002095 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002096 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002098 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002099 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002100 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 }
2102
2103 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002104 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002105 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002107 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 }
2109
2110 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002111 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002112 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002114 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 }
2116}
2117
2118// Test we can set the correct statistics on all send streams.
2119TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2120 SetupForMultiSendStream();
2121
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002123 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002125 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 }
solenberg85a04962015-10-27 03:35:21 -07002127
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002128 // Create a receive stream to check that none of the send streams end up in
2129 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002133 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002134 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002135 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136
solenberg85a04962015-10-27 03:35:21 -07002137 // Check stats for the added streams.
2138 {
2139 cricket::VoiceMediaInfo info;
2140 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141
solenberg85a04962015-10-27 03:35:21 -07002142 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002143 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002144 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002145 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002146 }
hbos1acfbd22016-11-17 23:43:29 -08002147 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002148
2149 // We have added one receive stream. We should see empty stats.
2150 EXPECT_EQ(info.receivers.size(), 1u);
2151 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 }
solenberg1ac56142015-10-13 03:58:19 -07002153
solenberg2100c0b2017-03-01 11:29:29 -08002154 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002155 {
2156 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002157 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002158 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002159 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002160 EXPECT_EQ(0u, info.receivers.size());
2161 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002162
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002163 // Deliver a new packet - a default receive stream should be created and we
2164 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002165 {
2166 cricket::VoiceMediaInfo info;
2167 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2168 SetAudioReceiveStreamStats();
2169 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002170 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002171 EXPECT_EQ(1u, info.receivers.size());
2172 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002173 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002174 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175}
2176
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177// Test that we can add and remove receive streams, and do proper send/playout.
2178// We can receive on multiple streams while sending one stream.
2179TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002180 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181
solenberg1ac56142015-10-13 03:58:19 -07002182 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002184 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
solenberg1ac56142015-10-13 03:58:19 -07002186 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002188 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002189 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002190
solenberg1ac56142015-10-13 03:58:19 -07002191 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002192 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
2194 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002195 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2196 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2197 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198
2199 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002200 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202
2203 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002204 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002205 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2206 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002207
aleloi84ef6152016-08-04 05:28:21 -07002208 // Restart playout and make sure recv streams are played out.
2209 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002210 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2211 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002212
aleloi84ef6152016-08-04 05:28:21 -07002213 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2215 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216}
2217
wu@webrtc.org97077a32013-10-25 21:18:33 +00002218TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002219 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002220 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2221 .Times(1)
2222 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002223 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2224 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002225 send_parameters_.options.tx_agc_target_dbov = 3;
2226 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2227 send_parameters_.options.tx_agc_limiter = true;
2228 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002229 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2230 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2231 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002232 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002233}
2234
minyue6b825df2016-10-31 04:08:32 -07002235TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2236 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002237 send_parameters_.options.audio_network_adaptor = true;
2238 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002239 SetSendParameters(send_parameters_);
2240 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002241 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002242}
2243
2244TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2245 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002246 send_parameters_.options.audio_network_adaptor = true;
2247 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002248 SetSendParameters(send_parameters_);
2249 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002250 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002251 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002252 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002253 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002254 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002255}
2256
2257TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2258 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002259 send_parameters_.options.audio_network_adaptor = true;
2260 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002261 SetSendParameters(send_parameters_);
2262 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002263 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002264 const int initial_num = call_.GetNumCreatedSendStreams();
2265 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002266 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002267 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2268 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002269 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002270 // AudioSendStream not expected to be recreated.
2271 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2272 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002273 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002274}
2275
michaelt6672b262017-01-11 10:17:59 -08002276class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2277 : public WebRtcVoiceEngineTestFake {
2278 public:
2279 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2280 : WebRtcVoiceEngineTestFake(
2281 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2282 "Enabled/") {}
2283};
2284
2285TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2286 EXPECT_TRUE(SetupSendStream());
2287 cricket::AudioSendParameters parameters;
2288 parameters.codecs.push_back(kOpusCodec);
2289 SetSendParameters(parameters);
2290 const int initial_num = call_.GetNumCreatedSendStreams();
2291 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2292
2293 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2294 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002295 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2296 constexpr int kMinOverheadBps =
2297 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002298
2299 constexpr int kOpusMinBitrateBps = 6000;
2300 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002301 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002302 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002303 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002304 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002305
Oskar Sundbom78807582017-11-16 11:09:55 +01002306 parameters.options.audio_network_adaptor = true;
2307 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002308 SetSendParameters(parameters);
2309
ossu11bfc532017-02-16 05:37:06 -08002310 constexpr int kMinOverheadWithAnaBps =
2311 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002312
2313 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002314 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002315
minyuececec102017-03-27 13:04:25 -07002316 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002317 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002318}
2319
minyuececec102017-03-27 13:04:25 -07002320// This test is similar to
2321// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2322// additional field trial.
2323TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2324 SetRtpSendParameterUpdatesMaxBitrate) {
2325 EXPECT_TRUE(SetupSendStream());
2326 cricket::AudioSendParameters send_parameters;
2327 send_parameters.codecs.push_back(kOpusCodec);
2328 SetSendParameters(send_parameters);
2329
2330 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2331 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2332 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2333
2334 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002335 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002336 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2337
2338 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2339#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2340 constexpr int kMinOverhead = 3333;
2341#else
2342 constexpr int kMinOverhead = 6666;
2343#endif
2344 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2345}
2346
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002347// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002348// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002350 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002351 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002352}
2353
2354TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2355 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002356 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002357 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002358 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002359 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002360 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002361 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002362 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363
solenberg85a04962015-10-27 03:35:21 -07002364 // Check stats for the added streams.
2365 {
2366 cricket::VoiceMediaInfo info;
2367 EXPECT_EQ(true, channel_->GetStats(&info));
2368
2369 // We have added one send stream. We should see the stats we've set.
2370 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002371 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002372 // We have added one receive stream. We should see empty stats.
2373 EXPECT_EQ(info.receivers.size(), 1u);
2374 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2375 }
solenberg1ac56142015-10-13 03:58:19 -07002376
solenberg566ef242015-11-06 15:34:49 -08002377 // Start sending - this affects some reported stats.
2378 {
2379 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002380 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002381 EXPECT_EQ(true, channel_->GetStats(&info));
2382 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002383 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002384 }
2385
solenberg2100c0b2017-03-01 11:29:29 -08002386 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002387 {
2388 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002389 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002390 EXPECT_EQ(true, channel_->GetStats(&info));
2391 EXPECT_EQ(1u, info.senders.size());
2392 EXPECT_EQ(0u, info.receivers.size());
2393 }
solenberg1ac56142015-10-13 03:58:19 -07002394
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002395 // Deliver a new packet - a default receive stream should be created and we
2396 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002397 {
2398 cricket::VoiceMediaInfo info;
2399 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2400 SetAudioReceiveStreamStats();
2401 EXPECT_EQ(true, channel_->GetStats(&info));
2402 EXPECT_EQ(1u, info.senders.size());
2403 EXPECT_EQ(1u, info.receivers.size());
2404 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002405 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002406 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002407}
2408
2409// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002410// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002411TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002412 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002413 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2414 EXPECT_TRUE(AddRecvStream(kSsrcY));
2415 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002416}
2417
2418// Test that the local SSRC is the same on sending and receiving channels if the
2419// receive channel is created before the send channel.
2420TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002421 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002422 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002424 cricket::StreamParams::CreateLegacy(kSsrcX)));
2425 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2426 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that we can properly receive packets.
2430TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002431 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002432 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002434
2435 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2436 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437}
2438
2439// Test that we can properly receive packets on multiple streams.
2440TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002441 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002442 const uint32_t ssrc1 = 1;
2443 const uint32_t ssrc2 = 2;
2444 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002445 EXPECT_TRUE(AddRecvStream(ssrc1));
2446 EXPECT_TRUE(AddRecvStream(ssrc2));
2447 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002449 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002450 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002452 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 }
mflodman3d7db262016-04-29 00:57:13 -07002454
2455 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2456 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2457 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2458
2459 EXPECT_EQ(s1.received_packets(), 0);
2460 EXPECT_EQ(s2.received_packets(), 0);
2461 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002462
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002464 EXPECT_EQ(s1.received_packets(), 0);
2465 EXPECT_EQ(s2.received_packets(), 0);
2466 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002467
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002468 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002469 EXPECT_EQ(s1.received_packets(), 1);
2470 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2471 EXPECT_EQ(s2.received_packets(), 0);
2472 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002473
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002475 EXPECT_EQ(s1.received_packets(), 1);
2476 EXPECT_EQ(s2.received_packets(), 1);
2477 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2478 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002479
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002481 EXPECT_EQ(s1.received_packets(), 1);
2482 EXPECT_EQ(s2.received_packets(), 1);
2483 EXPECT_EQ(s3.received_packets(), 1);
2484 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002485
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2487 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2488 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489}
2490
solenberg2100c0b2017-03-01 11:29:29 -08002491// Test that receiving on an unsignaled stream works (a stream is created).
2492TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002493 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002494 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2495
solenberg7e63ef02015-11-20 00:19:43 -08002496 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002497
2498 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002499 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2500 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002501}
2502
solenberg2100c0b2017-03-01 11:29:29 -08002503// Test that receiving N unsignaled stream works (streams will be created), and
2504// that packets are forwarded to them all.
2505TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002507 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002508 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2509
solenberg2100c0b2017-03-01 11:29:29 -08002510 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002511 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002512 rtc::SetBE32(&packet[8], ssrc);
2513 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002514
solenberg2100c0b2017-03-01 11:29:29 -08002515 // Verify we have one new stream for each loop iteration.
2516 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002517 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2518 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002519 }
mflodman3d7db262016-04-29 00:57:13 -07002520
solenberg2100c0b2017-03-01 11:29:29 -08002521 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002522 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002523 rtc::SetBE32(&packet[8], ssrc);
2524 DeliverPacket(packet, sizeof(packet));
2525
solenbergebb349d2017-03-13 05:46:15 -07002526 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002527 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2528 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2529 }
2530
2531 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2532 constexpr uint32_t kAnotherSsrc = 667;
2533 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002534 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002535
2536 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002537 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002538 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002539 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002540 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2541 EXPECT_EQ(2, streams[i]->received_packets());
2542 }
2543 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2544 EXPECT_EQ(1, streams[i]->received_packets());
2545 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002546 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002547}
2548
solenberg2100c0b2017-03-01 11:29:29 -08002549// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002550// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002551TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002552 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002553 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002554 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2555
2556 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002557 const uint32_t signaled_ssrc = 1;
2558 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002559 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002560 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002561 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2562 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002563 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002564
2565 // Note that the first unknown SSRC cannot be 0, because we only support
2566 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002567 const uint32_t unsignaled_ssrc = 7011;
2568 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002569 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002570 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2571 packet, sizeof(packet)));
2572 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2573
2574 DeliverPacket(packet, sizeof(packet));
2575 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2576
2577 rtc::SetBE32(&packet[8], signaled_ssrc);
2578 DeliverPacket(packet, sizeof(packet));
2579 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2580 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002581}
2582
solenberg4904fb62017-02-17 12:01:14 -08002583// Two tests to verify that adding a receive stream with the same SSRC as a
2584// previously added unsignaled stream will only recreate underlying stream
2585// objects if the stream parameters have changed.
2586TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
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 not recreated when a
2596 // stream with SSRC=1 is added.
2597 const auto& streams = call_.GetAudioReceiveStreams();
2598 EXPECT_EQ(1, streams.size());
2599 int audio_receive_stream_id = streams.front()->id();
2600 EXPECT_TRUE(AddRecvStream(1));
2601 EXPECT_EQ(1, streams.size());
2602 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2603}
2604
2605TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2606 EXPECT_TRUE(SetupChannel());
2607
2608 // Spawn unsignaled stream with SSRC=1.
2609 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2610 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2611 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2612 sizeof(kPcmuFrame)));
2613
2614 // Verify that the underlying stream object in Call *is* recreated when a
2615 // stream with SSRC=1 is added, and which has changed stream parameters.
2616 const auto& streams = call_.GetAudioReceiveStreams();
2617 EXPECT_EQ(1, streams.size());
2618 int audio_receive_stream_id = streams.front()->id();
2619 cricket::StreamParams stream_params;
2620 stream_params.ssrcs.push_back(1);
2621 stream_params.sync_label = "sync_label";
2622 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2623 EXPECT_EQ(1, streams.size());
2624 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2625}
2626
solenberg0a617e22015-10-20 15:49:38 -07002627// Test that we properly handle failures to add a receive stream.
2628TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002629 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002630 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002631 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002632}
2633
solenberg0a617e22015-10-20 15:49:38 -07002634// Test that we properly handle failures to add a send stream.
2635TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002636 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002637 voe_.set_fail_create_channel(true);
2638 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2639}
2640
solenberg1ac56142015-10-13 03:58:19 -07002641// Test that AddRecvStream creates new stream.
2642TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002643 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002644 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002645 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002646 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002647}
2648
2649// Test that after adding a recv stream, we do not decode more codecs than
2650// those previously passed into SetRecvCodecs.
2651TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002653 cricket::AudioRecvParameters parameters;
2654 parameters.codecs.push_back(kIsacCodec);
2655 parameters.codecs.push_back(kPcmuCodec);
2656 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002657 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002658 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2659 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2660 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002661}
2662
2663// Test that we properly clean up any streams that were added, even if
2664// not explicitly removed.
2665TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002666 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002667 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_TRUE(AddRecvStream(1));
2669 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002670 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2671 delete channel_;
2672 channel_ = NULL;
2673 EXPECT_EQ(0, voe_.GetNumChannels());
2674}
2675
wu@webrtc.org78187522013-10-07 23:32:02 +00002676TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002677 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002678 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002679}
2680
2681TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002682 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002683 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002684 // Manually delete channel to simulate a failure.
2685 int channel = voe_.GetLastChannel();
2686 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2687 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002688 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002689 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002690 EXPECT_NE(channel, new_channel);
2691 // The last created channel is deleted too.
2692 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002693}
2694
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002695// Test the InsertDtmf on default send stream as caller.
2696TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002697 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002698}
2699
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002700// Test the InsertDtmf on default send stream as callee
2701TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002702 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002703}
2704
2705// Test the InsertDtmf on specified send stream as caller.
2706TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002707 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002708}
2709
2710// Test the InsertDtmf on specified send stream as callee.
2711TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002712 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713}
2714
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002716 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002717 EXPECT_CALL(adm_,
2718 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2719 EXPECT_CALL(adm_,
2720 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2721 EXPECT_CALL(adm_,
2722 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002723
solenberg246b8172015-12-08 09:50:23 -08002724 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2725 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002726
solenberg246b8172015-12-08 09:50:23 -08002727 // Nothing set in AudioOptions, so everything should be as default.
2728 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002729 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002730 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002731 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2732 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733
2734 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002735 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2736 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002737 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002738 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739
2740 // Turn echo cancellation back on, with settings, and make sure
2741 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002742 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2743 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002744 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002745 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002747 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2748 // control.
solenberg76377c52017-02-21 00:54:31 -08002749 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2750 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002751 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002753
2754 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.delay_agnostic_aec = false;
2758 send_parameters_.options.extended_filter_aec = false;
2759 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002761
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002762 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002763 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002765 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002766 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002767
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002771 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002772 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002773 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775
2776 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002777 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002779 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002780 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002781 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783
2784 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002787 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002788 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002789 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002790 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2792 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002793 send_parameters_.options.noise_suppression = false;
2794 send_parameters_.options.highpass_filter = false;
2795 send_parameters_.options.typing_detection = false;
2796 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002797 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002798 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799
solenberg1ac56142015-10-13 03:58:19 -07002800 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002801 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2802 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002803 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002804 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002805 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002806 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2807 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2808 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002809 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002810}
2811
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002812TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002813 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002814 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002815 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002816 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002817 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002818 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002819 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002820 EXPECT_CALL(adm_,
2821 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2822 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2823 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002824 webrtc::AudioProcessing::Config apm_config;
2825 EXPECT_CALL(*apm_, GetConfig())
2826 .Times(10)
2827 .WillRepeatedly(ReturnPointee(&apm_config));
2828 EXPECT_CALL(*apm_, ApplyConfig(_))
2829 .Times(10)
2830 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002831 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002832
kwiberg686a8ef2016-02-26 03:00:35 -08002833 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002834 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002835 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002836 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002837 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002838 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002839
2840 // Have to add a stream to make SetSend work.
2841 cricket::StreamParams stream1;
2842 stream1.ssrcs.push_back(1);
2843 channel1->AddSendStream(stream1);
2844 cricket::StreamParams stream2;
2845 stream2.ssrcs.push_back(2);
2846 channel2->AddSendStream(stream2);
2847
2848 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002849 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002850 parameters_options_all.options.echo_cancellation = true;
2851 parameters_options_all.options.auto_gain_control = true;
2852 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002853 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2854 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002855 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002856 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002857 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002859 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002860 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002861 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002862 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863
2864 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002865 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002866 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002867 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2868 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002869 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002870 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002871 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002873 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002874 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002875 expected_options.echo_cancellation = true;
2876 expected_options.auto_gain_control = true;
2877 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002878 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
2880 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002882 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002885 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002887 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002888 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002889 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002890 expected_options.echo_cancellation = true;
2891 expected_options.auto_gain_control = false;
2892 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002893 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002894
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002897 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002898 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002899 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002900 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002901 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902
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(true)).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 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002913 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002917 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002919 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002920 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2921 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002922 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2923 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002924 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002926 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002927 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002928 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002930 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002931 expected_options.echo_cancellation = true;
2932 expected_options.auto_gain_control = false;
2933 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002934 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935}
2936
wu@webrtc.orgde305012013-10-31 15:40:38 +00002937// This test verifies DSCP settings are properly applied on voice media channel.
2938TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002939 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002940 cricket::FakeNetworkInterface network_interface;
2941 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002942 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002943
peahb1c9d1d2017-07-25 15:45:24 -07002944 webrtc::AudioProcessing::Config apm_config;
2945 EXPECT_CALL(*apm_, GetConfig())
2946 .Times(3)
2947 .WillRepeatedly(ReturnPointee(&apm_config));
2948 EXPECT_CALL(*apm_, ApplyConfig(_))
2949 .Times(3)
2950 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002951 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002952
solenbergbc37fc82016-04-04 09:54:44 -07002953 channel.reset(
2954 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002955 channel->SetInterface(&network_interface);
2956 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2957 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2958
2959 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002960 channel.reset(
2961 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002962 channel->SetInterface(&network_interface);
2963 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2964
2965 // Verify that setting the option to false resets the
2966 // DiffServCodePoint.
2967 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002968 channel.reset(
2969 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002970 channel->SetInterface(&network_interface);
2971 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2972 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2973
2974 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002975}
2976
solenberg1ac56142015-10-13 03:58:19 -07002977TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002978 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 cricket::WebRtcVoiceMediaChannel* media_channel =
2980 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002981 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002982 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002983 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002984 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2985 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2986 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002987 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002988 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989}
2990
solenberg1ac56142015-10-13 03:58:19 -07002991TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002992 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002994 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2995 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2996 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002997 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002998 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002999 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3000 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003001 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003002 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003003 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003004 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005}
3006
solenberg4bac9c52015-10-09 02:32:53 -07003007TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003008 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003009 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003011 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003013 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3014 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3015 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003016}
3017
solenberg2100c0b2017-03-01 11:29:29 -08003018TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003019 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003020
3021 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003022 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003023 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3024
3025 // Should remember the volume "2" which will be set on new unsignaled streams,
3026 // and also set the gain to 2 on existing unsignaled streams.
3027 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3028 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3029
3030 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3031 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3032 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3033 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3034 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3035 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3036
3037 // Setting gain with SSRC=0 should affect all unsignaled streams.
3038 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003039 if (kMaxUnsignaledRecvStreams > 1) {
3040 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3041 }
solenberg2100c0b2017-03-01 11:29:29 -08003042 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3043
3044 // Setting gain on an individual stream affects only that.
3045 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003046 if (kMaxUnsignaledRecvStreams > 1) {
3047 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3048 }
solenberg2100c0b2017-03-01 11:29:29 -08003049 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050}
3051
pbos8fc7fa72015-07-15 08:02:58 -07003052TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003053 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003054 const std::string kSyncLabel = "AvSyncLabel";
3055
solenbergff976312016-03-30 23:28:51 -07003056 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003057 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3058 sp.sync_label = kSyncLabel;
3059 // Creating two channels to make sure that sync label is set properly for both
3060 // the default voice channel and following ones.
3061 EXPECT_TRUE(channel_->AddRecvStream(sp));
3062 sp.ssrcs[0] += 1;
3063 EXPECT_TRUE(channel_->AddRecvStream(sp));
3064
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003065 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003066 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003067 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003068 << "SyncGroup should be set based on sync_label";
3069 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003070 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003071 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003072}
3073
solenberg3a941542015-11-16 07:34:50 -08003074// TODO(solenberg): Remove, once recv streams are configured through Call.
3075// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003076TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003077 // Test that setting the header extensions results in the expected state
3078 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003079 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003080 ssrcs.push_back(223);
3081 ssrcs.push_back(224);
3082
solenbergff976312016-03-30 23:28:51 -07003083 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003084 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003085 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003086 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003087 cricket::StreamParams::CreateLegacy(ssrc)));
3088 }
3089
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003090 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003091 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003092 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093 EXPECT_NE(nullptr, s);
3094 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3095 }
3096
3097 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003098 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003099 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003100 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003101 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003102 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003103 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003104 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 EXPECT_NE(nullptr, s);
3106 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003107 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3108 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109 for (const auto& s_ext : s_exts) {
3110 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003111 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 }
3113 }
3114 }
3115 }
3116
3117 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003118 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003119 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003120 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003121 EXPECT_NE(nullptr, s);
3122 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3123 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003124}
3125
3126TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3127 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003128 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003129 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 static const unsigned char kRtcp[] = {
3131 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3132 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3135 };
jbaucheec21bd2016-03-20 06:15:43 -07003136 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003137
solenbergff976312016-03-30 23:28:51 -07003138 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 cricket::WebRtcVoiceMediaChannel* media_channel =
3140 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003141 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003142 EXPECT_TRUE(media_channel->AddRecvStream(
3143 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3144
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003145 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003147 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003148 EXPECT_EQ(0, s->received_packets());
3149 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3150 EXPECT_EQ(1, s->received_packets());
3151 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3152 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003153}
Minyue2013aec2015-05-13 14:14:42 +02003154
solenberg0a617e22015-10-20 15:49:38 -07003155// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003156// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003157TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003158 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003159 EXPECT_TRUE(AddRecvStream(kSsrcY));
3160 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003161 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003162 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3163 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3164 EXPECT_TRUE(AddRecvStream(kSsrcW));
3165 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003166}
3167
solenberg7602aab2016-11-14 11:30:07 -08003168TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3169 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003170 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003171 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003172 cricket::StreamParams::CreateLegacy(kSsrcY)));
3173 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3174 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3175 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003176 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003177 cricket::StreamParams::CreateLegacy(kSsrcW)));
3178 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3179 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003180}
stefan658910c2015-09-03 05:48:32 -07003181
deadbeef884f5852016-01-15 09:20:04 -08003182TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003183 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003184 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3185 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003186
3187 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003188 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3189 EXPECT_TRUE(AddRecvStream(kSsrcX));
3190 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003191
3192 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003193 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3194 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003195
3196 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003197 channel_->SetRawAudioSink(kSsrcX, nullptr);
3198 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003199}
3200
solenberg2100c0b2017-03-01 11:29:29 -08003201TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003202 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003203 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3204 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003205 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3206 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003207
3208 // Should be able to set a default sink even when no stream exists.
3209 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3210
solenberg2100c0b2017-03-01 11:29:29 -08003211 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3212 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003213 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003214 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003215
3216 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003217 channel_->SetRawAudioSink(kSsrc0, nullptr);
3218 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003219
3220 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003221 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3222 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003223
3224 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003225 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003226 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003227 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3228
3229 // Spawn another unsignaled stream - it should be assigned the default sink
3230 // and the previous unsignaled stream should lose it.
3231 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3232 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3233 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3234 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3237 }
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3239
3240 // Reset the default sink - the second unsignaled stream should lose it.
3241 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003242 if (kMaxUnsignaledRecvStreams > 1) {
3243 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3244 }
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3246
3247 // Try setting the default sink while two streams exists.
3248 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003249 if (kMaxUnsignaledRecvStreams > 1) {
3250 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3251 }
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3253
3254 // Try setting the sink for the first unsignaled stream using its known SSRC.
3255 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003256 if (kMaxUnsignaledRecvStreams > 1) {
3257 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3258 }
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003260 if (kMaxUnsignaledRecvStreams > 1) {
3261 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3262 }
deadbeef884f5852016-01-15 09:20:04 -08003263}
3264
skvlad7a43d252016-03-22 15:32:27 -07003265// Test that, just like the video channel, the voice channel communicates the
3266// network state to the call.
3267TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003268 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003269
3270 EXPECT_EQ(webrtc::kNetworkUp,
3271 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3272 EXPECT_EQ(webrtc::kNetworkUp,
3273 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3274
3275 channel_->OnReadyToSend(false);
3276 EXPECT_EQ(webrtc::kNetworkDown,
3277 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3278 EXPECT_EQ(webrtc::kNetworkUp,
3279 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3280
3281 channel_->OnReadyToSend(true);
3282 EXPECT_EQ(webrtc::kNetworkUp,
3283 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3284 EXPECT_EQ(webrtc::kNetworkUp,
3285 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3286}
3287
aleloi18e0b672016-10-04 02:45:47 -07003288// Test that playout is still started after changing parameters
3289TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3290 SetupRecvStream();
3291 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003292 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003293
3294 // Changing RTP header extensions will recreate the AudioReceiveStream.
3295 cricket::AudioRecvParameters parameters;
3296 parameters.extensions.push_back(
3297 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3298 channel_->SetRecvParameters(parameters);
3299
solenberg2100c0b2017-03-01 11:29:29 -08003300 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003301}
3302
Zhi Huangfa266ef2017-12-13 10:27:46 -08003303// Tests when GetSources is called with non-existing ssrc, it will return an
3304// empty list of RtpSource without crashing.
3305TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3306 // Setup an recv stream with |kSsrcX|.
3307 SetupRecvStream();
3308 cricket::WebRtcVoiceMediaChannel* media_channel =
3309 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3310 // Call GetSources with |kSsrcY| which doesn't exist.
3311 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3312 EXPECT_EQ(0u, sources.size());
3313}
3314
stefan658910c2015-09-03 05:48:32 -07003315// Tests that the library initializes and shuts down properly.
3316TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003317 // If the VoiceEngine wants to gather available codecs early, that's fine but
3318 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003319 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003320 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3321 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003322 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003323 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003324 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003325 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003326 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003327 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003328 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003329 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3330 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003331 EXPECT_TRUE(channel != nullptr);
3332 delete channel;
solenbergff976312016-03-30 23:28:51 -07003333}
stefan658910c2015-09-03 05:48:32 -07003334
solenbergff976312016-03-30 23:28:51 -07003335// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003336TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3337 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003338 EXPECT_CALL(adm, AddRef()).Times(3);
3339 EXPECT_CALL(adm, Release())
3340 .Times(3)
3341 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003342 {
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(
ossueb1fde42017-05-02 06:46:30 -07003346 &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();
skvlad11a9cbf2016-10-07 11:53:05 -07003349 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003350 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003351 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003352 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3353 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3354 EXPECT_TRUE(channel != nullptr);
3355 delete channel;
3356 }
stefan658910c2015-09-03 05:48:32 -07003357}
3358
ossu20a4b3f2017-04-27 02:08:52 -07003359// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3360TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003361 // TODO(ossu): Why are the payload types of codecs with non-static payload
3362 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003363 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003364 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3365 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003366 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003367 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003368 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003369 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003370 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003371 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3372 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3373 (clockrate == 0 || codec.clockrate == clockrate);
3374 };
3375 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003376 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003377 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003378 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003379 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003380 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003381 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003382 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003383 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003384 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003385 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003386 EXPECT_EQ(126, codec.id);
3387 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3388 // Remove these checks once both send and receive side assigns payload types
3389 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003390 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003391 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003392 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003393 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003394 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003395 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003396 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003397 EXPECT_EQ(111, codec.id);
3398 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3399 EXPECT_EQ("10", codec.params.find("minptime")->second);
3400 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3401 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003402 }
3403 }
stefan658910c2015-09-03 05:48:32 -07003404}
3405
3406// Tests that VoE supports at least 32 channels
3407TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003408 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003409 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3410 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003411 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003412 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003413 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003414 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003415 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003416 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003417 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003418
3419 cricket::VoiceMediaChannel* channels[32];
3420 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003421 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003422 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3423 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003424 if (!channel)
3425 break;
stefan658910c2015-09-03 05:48:32 -07003426 channels[num_channels++] = channel;
3427 }
3428
tfarina5237aaf2015-11-10 23:44:30 -08003429 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003430 EXPECT_EQ(expected, num_channels);
3431
3432 while (num_channels > 0) {
3433 delete channels[--num_channels];
3434 }
stefan658910c2015-09-03 05:48:32 -07003435}
3436
3437// Test that we set our preferred codecs properly.
3438TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003439 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3440 // - Check that our builtin codecs are usable by Channel.
3441 // - The codecs provided by the engine is usable by Channel.
3442 // It does not check that the codecs in the RecvParameters are actually
3443 // what we sent in - though it's probably reasonable to expect so, if
3444 // SetRecvParameters returns true.
3445 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003446 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003447 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3448 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003449 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003450 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003451 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003452 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003453 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003454 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003455 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003456 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3457 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003458 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003459 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003460 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003461}
ossu9def8002017-02-09 05:14:32 -08003462
3463TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3464 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003465 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3466 {48000, 2, 16000, 10000, 20000}};
3467 spec1.info.allow_comfort_noise = false;
3468 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003469 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003470 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3471 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003472 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003473 specs.push_back(webrtc::AudioCodecSpec{
3474 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3475 {16000, 1, 13300}});
3476 specs.push_back(
3477 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3478 specs.push_back(
3479 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003480
ossueb1fde42017-05-02 06:46:30 -07003481 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3482 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3483 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003484 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003485 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003486 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003487 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003488
peaha9cc40b2017-06-29 08:32:09 -07003489 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3490 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003491 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003492 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003493 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003494 auto codecs = engine.recv_codecs();
3495 EXPECT_EQ(11, codecs.size());
3496
3497 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3498 // check the actual values safely, to provide better test results.
3499 auto get_codec =
3500 [&codecs](size_t index) -> const cricket::AudioCodec& {
3501 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3502 if (codecs.size() > index)
3503 return codecs[index];
3504 return missing_codec;
3505 };
3506
3507 // Ensure the general codecs are generated first and in order.
3508 for (size_t i = 0; i != specs.size(); ++i) {
3509 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3510 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3511 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3512 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3513 }
3514
3515 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003516 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003517 auto find_codec =
3518 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3519 for (size_t i = 0; i != codecs.size(); ++i) {
3520 const cricket::AudioCodec& codec = codecs[i];
3521 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3522 codec.clockrate == format.clockrate_hz &&
3523 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003524 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003525 }
3526 }
3527 return -1;
3528 };
3529
3530 // Ensure all supplementary codecs are generated last. Their internal ordering
3531 // is not important.
3532 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3533 const int num_specs = static_cast<int>(specs.size());
3534 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3535 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3536 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3537 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3538 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3539 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3540 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3541}