blob: b65241ff92922e1c930947c7b3bdb0fc82a23ed2 [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));
127 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100128
129 // Teardown.
130 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
131 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
132 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
133 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
134 EXPECT_CALL(*adm, Release())
135 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700136}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200137} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138
solenbergff976312016-03-30 23:28:51 -0700139// Tests that our stub library "works".
140TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700141 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700142 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700143 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
144 new rtc::RefCountedObject<
145 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700146 webrtc::AudioProcessing::Config apm_config;
147 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
148 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700149 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700150 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800151 StrictMock<MockTransmitMixer> transmit_mixer;
152 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700153 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700154 EXPECT_FALSE(voe.IsInited());
155 {
ossuc54071d2016-08-17 02:45:41 -0700156 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700157 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700158 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700159 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700160 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700161 EXPECT_TRUE(voe.IsInited());
162 }
163 EXPECT_FALSE(voe.IsInited());
164}
165
deadbeef884f5852016-01-15 09:20:04 -0800166class FakeAudioSink : public webrtc::AudioSinkInterface {
167 public:
168 void OnData(const Data& audio) override {}
169};
170
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800171class FakeAudioSource : public cricket::AudioSource {
172 void SetSink(Sink* sink) override {}
173};
174
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175class WebRtcVoiceEngineTestFake : public testing::Test {
176 public:
stefanba4c0e42016-02-04 04:12:24 -0800177 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
178
179 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700180 : apm_(new rtc::RefCountedObject<
181 StrictMock<webrtc::test::MockAudioProcessing>>()),
182 apm_gc_(*apm_->gain_control()),
183 apm_ec_(*apm_->echo_cancellation()),
184 apm_ns_(*apm_->noise_suppression()),
185 apm_vd_(*apm_->voice_detection()),
186 call_(webrtc::Call::Config(&event_log_)),
187 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700188 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800189 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700190 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800191 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700192 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
193 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700194 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700195 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800196 // Default Options.
197 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
198 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100199 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
200 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800201 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100202 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
203 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800204 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
205 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
206 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
207 // Init does not overwrite default AGC config.
208 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
209 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
210 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800211 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
212 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700213 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800214 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700215 // factories. Those tests should probably be moved elsewhere.
216 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
217 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
218 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700219 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700220 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700221 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200222 send_parameters_.codecs.push_back(kPcmuCodec);
223 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100224
solenberg76377c52017-02-21 00:54:31 -0800225 // Default Options.
226 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 }
solenberg8189b022016-06-14 12:13:00 -0700228
solenbergff976312016-03-30 23:28:51 -0700229 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700230 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700231 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
232 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200233 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000234 }
solenberg8189b022016-06-14 12:13:00 -0700235
solenbergff976312016-03-30 23:28:51 -0700236 bool SetupRecvStream() {
237 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700238 return false;
239 }
solenberg2100c0b2017-03-01 11:29:29 -0800240 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700241 }
solenberg8189b022016-06-14 12:13:00 -0700242
solenbergff976312016-03-30 23:28:51 -0700243 bool SetupSendStream() {
244 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000245 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 }
solenberg2100c0b2017-03-01 11:29:29 -0800247 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800248 return false;
249 }
peaha9cc40b2017-06-29 08:32:09 -0700250 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800251 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 }
solenberg8189b022016-06-14 12:13:00 -0700253
254 bool AddRecvStream(uint32_t ssrc) {
255 EXPECT_TRUE(channel_);
256 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
257 }
258
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000259 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700260 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700261 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800262 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
263 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700264 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800265 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000266 }
solenberg8189b022016-06-14 12:13:00 -0700267
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700269 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000270 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 }
solenberg8189b022016-06-14 12:13:00 -0700272
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200273 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275 }
276
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100277 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
278 const auto* send_stream = call_.GetAudioSendStream(ssrc);
279 EXPECT_TRUE(send_stream);
280 return *send_stream;
281 }
282
deadbeef884f5852016-01-15 09:20:04 -0800283 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
284 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
285 EXPECT_TRUE(recv_stream);
286 return *recv_stream;
287 }
288
solenberg3a941542015-11-16 07:34:50 -0800289 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800290 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800291 }
292
solenberg7add0582015-11-20 09:59:34 -0800293 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800294 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800295 }
296
solenberg059fb442016-10-26 05:12:24 -0700297 void SetSend(bool enable) {
298 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700299 if (enable) {
300 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
301 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
302 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700303 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700304 }
solenberg059fb442016-10-26 05:12:24 -0700305 channel_->SetSend(enable);
306 }
307
308 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700309 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700310 ASSERT_TRUE(channel_);
311 EXPECT_TRUE(channel_->SetSendParameters(params));
312 }
313
minyue6b825df2016-10-31 04:08:32 -0700314 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
315 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700316 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700317 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700318 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700319 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700320 }
321 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700322 }
323
solenbergffbbcac2016-11-17 05:25:37 -0800324 void TestInsertDtmf(uint32_t ssrc, bool caller,
325 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700326 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000327 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700328 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329 // send stream.
330 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800331 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000332 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000333
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700335 SetSendParameters(send_parameters_);
336 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800339 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700340 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000342
343 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700344 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800345 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000346 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800347 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000348 }
349
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800351 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100353 // Test send.
354 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800355 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100356 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800357 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800358 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800359 EXPECT_EQ(codec.id, telephone_event.payload_type);
360 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100361 EXPECT_EQ(2, telephone_event.event_code);
362 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 }
364
365 // Test that send bandwidth is set correctly.
366 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000367 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
368 // |expected_result| is the expected result from SetMaxSendBandwidth().
369 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700370 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
371 int max_bitrate,
372 bool expected_result,
373 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200374 cricket::AudioSendParameters parameters;
375 parameters.codecs.push_back(codec);
376 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700377 if (expected_result) {
378 SetSendParameters(parameters);
379 } else {
380 EXPECT_FALSE(channel_->SetSendParameters(parameters));
381 }
solenberg2100c0b2017-03-01 11:29:29 -0800382 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000383 }
384
skvlade0d46372016-04-07 22:59:22 -0700385 // Sets the per-stream maximum bitrate limit for the specified SSRC.
386 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700387 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700388 EXPECT_EQ(1UL, parameters.encodings.size());
389
Oskar Sundbom78807582017-11-16 11:09:55 +0100390 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700391 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700392 }
393
solenberg059fb442016-10-26 05:12:24 -0700394 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700395 cricket::AudioSendParameters send_parameters;
396 send_parameters.codecs.push_back(codec);
397 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700398 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700399 }
400
ossu20a4b3f2017-04-27 02:08:52 -0700401 void CheckSendCodecBitrate(int32_t ssrc,
402 const char expected_name[],
403 int expected_bitrate) {
404 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
405 EXPECT_EQ(expected_name, spec->format.name);
406 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700407 }
408
ossu20a4b3f2017-04-27 02:08:52 -0700409 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
410 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700411 }
412
minyue6b825df2016-10-31 04:08:32 -0700413 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
414 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
415 }
416
skvlade0d46372016-04-07 22:59:22 -0700417 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
418 int global_max,
419 int stream_max,
420 bool expected_result,
421 int expected_codec_bitrate) {
422 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800423 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700424
425 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700426 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800427 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700428
429 // Verify that reading back the parameters gives results
430 // consistent with the Set() result.
431 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800432 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700433 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
434 EXPECT_EQ(expected_result ? stream_max : -1,
435 resulting_parameters.encodings[0].max_bitrate_bps);
436
437 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800438 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700439 }
440
stefan13f1a0a2016-11-30 07:22:58 -0800441 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
442 int expected_min_bitrate_bps,
443 const char* start_bitrate_kbps,
444 int expected_start_bitrate_bps,
445 const char* max_bitrate_kbps,
446 int expected_max_bitrate_bps) {
447 EXPECT_TRUE(SetupSendStream());
448 auto& codecs = send_parameters_.codecs;
449 codecs.clear();
450 codecs.push_back(kOpusCodec);
451 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
452 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
453 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
454 SetSendParameters(send_parameters_);
455
456 EXPECT_EQ(expected_min_bitrate_bps,
457 call_.GetConfig().bitrate_config.min_bitrate_bps);
458 EXPECT_EQ(expected_start_bitrate_bps,
459 call_.GetConfig().bitrate_config.start_bitrate_bps);
460 EXPECT_EQ(expected_max_bitrate_bps,
461 call_.GetConfig().bitrate_config.max_bitrate_bps);
462 }
463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700465 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000466
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000467 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000469
470 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700471 send_parameters_.extensions.push_back(
472 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700473 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800474 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000475
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000476 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200477 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700478 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800479 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000480
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000481 // Ensure extension is set properly.
482 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700483 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
487 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000488
solenberg7add0582015-11-20 09:59:34 -0800489 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000490 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800491 cricket::StreamParams::CreateLegacy(kSsrcY)));
492 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
493 call_.GetAudioSendStream(kSsrcY));
494 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
495 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
496 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000497
498 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200499 send_parameters_.codecs.push_back(kPcmuCodec);
500 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700501 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800502 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
503 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504 }
505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700507 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000508
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000509 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000511
512 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700513 recv_parameters_.extensions.push_back(
514 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800515 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800516 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000517
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000518 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800519 recv_parameters_.extensions.clear();
520 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800521 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000522
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000523 // Ensure extension is set properly.
524 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700525 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800526 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800527 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
528 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
529 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000530
solenberg7add0582015-11-20 09:59:34 -0800531 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800532 EXPECT_TRUE(AddRecvStream(kSsrcY));
533 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
534 call_.GetAudioReceiveStream(kSsrcY));
535 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
536 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
537 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000538
539 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800540 recv_parameters_.extensions.clear();
541 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800542 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
543 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000544 }
545
solenberg85a04962015-10-27 03:35:21 -0700546 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
547 webrtc::AudioSendStream::Stats stats;
548 stats.local_ssrc = 12;
549 stats.bytes_sent = 345;
550 stats.packets_sent = 678;
551 stats.packets_lost = 9012;
552 stats.fraction_lost = 34.56f;
553 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100554 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700555 stats.ext_seqnum = 789;
556 stats.jitter_ms = 12;
557 stats.rtt_ms = 345;
558 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100559 stats.apm_statistics.delay_median_ms = 234;
560 stats.apm_statistics.delay_standard_deviation_ms = 567;
561 stats.apm_statistics.echo_return_loss = 890;
562 stats.apm_statistics.echo_return_loss_enhancement = 1234;
563 stats.apm_statistics.residual_echo_likelihood = 0.432f;
564 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100565 stats.ana_statistics.bitrate_action_counter = 321;
566 stats.ana_statistics.channel_action_counter = 432;
567 stats.ana_statistics.dtx_action_counter = 543;
568 stats.ana_statistics.fec_action_counter = 654;
569 stats.ana_statistics.frame_length_increase_counter = 765;
570 stats.ana_statistics.frame_length_decrease_counter = 876;
571 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700572 stats.typing_noise_detected = true;
573 return stats;
574 }
575 void SetAudioSendStreamStats() {
576 for (auto* s : call_.GetAudioSendStreams()) {
577 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200578 }
solenberg85a04962015-10-27 03:35:21 -0700579 }
solenberg566ef242015-11-06 15:34:49 -0800580 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
581 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700582 const auto stats = GetAudioSendStreamStats();
583 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
584 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
585 EXPECT_EQ(info.packets_sent, stats.packets_sent);
586 EXPECT_EQ(info.packets_lost, stats.packets_lost);
587 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
588 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800589 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700590 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
591 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
592 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
593 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100594 EXPECT_EQ(info.apm_statistics.delay_median_ms,
595 stats.apm_statistics.delay_median_ms);
596 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
597 stats.apm_statistics.delay_standard_deviation_ms);
598 EXPECT_EQ(info.apm_statistics.echo_return_loss,
599 stats.apm_statistics.echo_return_loss);
600 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
601 stats.apm_statistics.echo_return_loss_enhancement);
602 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
603 stats.apm_statistics.residual_echo_likelihood);
604 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
605 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700606 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
607 stats.ana_statistics.bitrate_action_counter);
608 EXPECT_EQ(info.ana_statistics.channel_action_counter,
609 stats.ana_statistics.channel_action_counter);
610 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
611 stats.ana_statistics.dtx_action_counter);
612 EXPECT_EQ(info.ana_statistics.fec_action_counter,
613 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700614 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
615 stats.ana_statistics.frame_length_increase_counter);
616 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
617 stats.ana_statistics.frame_length_decrease_counter);
618 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
619 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800620 EXPECT_EQ(info.typing_noise_detected,
621 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700622 }
623
624 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
625 webrtc::AudioReceiveStream::Stats stats;
626 stats.remote_ssrc = 123;
627 stats.bytes_rcvd = 456;
628 stats.packets_rcvd = 768;
629 stats.packets_lost = 101;
630 stats.fraction_lost = 23.45f;
631 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100632 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700633 stats.ext_seqnum = 678;
634 stats.jitter_ms = 901;
635 stats.jitter_buffer_ms = 234;
636 stats.jitter_buffer_preferred_ms = 567;
637 stats.delay_estimate_ms = 890;
638 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700639 stats.total_samples_received = 5678901;
640 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200641 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200642 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700643 stats.expand_rate = 5.67f;
644 stats.speech_expand_rate = 8.90f;
645 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200646 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700647 stats.accelerate_rate = 4.56f;
648 stats.preemptive_expand_rate = 7.89f;
649 stats.decoding_calls_to_silence_generator = 12;
650 stats.decoding_calls_to_neteq = 345;
651 stats.decoding_normal = 67890;
652 stats.decoding_plc = 1234;
653 stats.decoding_cng = 5678;
654 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700655 stats.decoding_muted_output = 3456;
656 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200657 return stats;
658 }
659 void SetAudioReceiveStreamStats() {
660 for (auto* s : call_.GetAudioReceiveStreams()) {
661 s->SetStats(GetAudioReceiveStreamStats());
662 }
663 }
664 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700665 const auto stats = GetAudioReceiveStreamStats();
666 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
667 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
668 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
669 EXPECT_EQ(info.packets_lost, stats.packets_lost);
670 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
671 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800672 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
674 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
675 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200676 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700677 stats.jitter_buffer_preferred_ms);
678 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
679 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700680 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
681 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200682 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200683 EXPECT_EQ(info.jitter_buffer_delay_seconds,
684 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700685 EXPECT_EQ(info.expand_rate, stats.expand_rate);
686 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
687 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200688 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700689 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
690 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200691 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700692 stats.decoding_calls_to_silence_generator);
693 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
694 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
695 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
696 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
697 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700698 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700699 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200700 }
hbos1acfbd22016-11-17 23:43:29 -0800701 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
702 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
703 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
704 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
705 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
706 codec.ToCodecParameters());
707 }
708 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
709 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
710 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
711 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
712 codec.ToCodecParameters());
713 }
714 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200715
peah8271d042016-11-22 07:24:52 -0800716 bool IsHighPassFilterEnabled() {
717 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
718 }
719
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700721 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700722 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800723 webrtc::test::MockGainControl& apm_gc_;
724 webrtc::test::MockEchoCancellation& apm_ec_;
725 webrtc::test::MockNoiseSuppression& apm_ns_;
726 webrtc::test::MockVoiceDetection& apm_vd_;
727 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700728 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200729 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700731 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700732 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200733 cricket::AudioSendParameters send_parameters_;
734 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800735 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700736 webrtc::AudioProcessing::Config apm_config_;
737
stefanba4c0e42016-02-04 04:12:24 -0800738 private:
739 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740};
741
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742// Tests that we can create and destroy a channel.
743TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700744 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745}
746
solenberg31fec402016-05-06 02:13:12 -0700747// Test that we can add a send stream and that it has the correct defaults.
748TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
749 EXPECT_TRUE(SetupChannel());
750 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800751 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
752 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
753 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700754 EXPECT_EQ("", config.rtp.c_name);
755 EXPECT_EQ(0u, config.rtp.extensions.size());
756 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
757 config.send_transport);
758}
759
760// Test that we can add a receive stream and that it has the correct defaults.
761TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
762 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800763 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700764 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800765 GetRecvStreamConfig(kSsrcX);
766 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700767 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
768 EXPECT_FALSE(config.rtp.transport_cc);
769 EXPECT_EQ(0u, config.rtp.extensions.size());
770 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
771 config.rtcp_send_transport);
772 EXPECT_EQ("", config.sync_group);
773}
774
stefanba4c0e42016-02-04 04:12:24 -0800775TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700776 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800777 bool opus_found = false;
778 for (cricket::AudioCodec codec : codecs) {
779 if (codec.name == "opus") {
780 EXPECT_TRUE(HasTransportCc(codec));
781 opus_found = true;
782 }
783 }
784 EXPECT_TRUE(opus_found);
785}
786
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787// Test that we set our inbound codecs properly, including changing PT.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200790 cricket::AudioRecvParameters parameters;
791 parameters.codecs.push_back(kIsacCodec);
792 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800793 parameters.codecs.push_back(kTelephoneEventCodec1);
794 parameters.codecs.push_back(kTelephoneEventCodec2);
795 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 parameters.codecs[2].id = 126;
797 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800798 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700799 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
800 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
801 {{0, {"PCMU", 8000, 1}},
802 {106, {"ISAC", 16000, 1}},
803 {126, {"telephone-event", 8000, 1}},
804 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805}
806
807// Test that we fail to set an unknown inbound codec.
808TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700809 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 cricket::AudioRecvParameters parameters;
811 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700812 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814}
815
816// Test that we fail if we have duplicate types in the inbound list.
817TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700818 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200819 cricket::AudioRecvParameters parameters;
820 parameters.codecs.push_back(kIsacCodec);
821 parameters.codecs.push_back(kCn16000Codec);
822 parameters.codecs[1].id = kIsacCodec.id;
823 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS without stereo parameters.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800834 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700835 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
836 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
837 {{0, {"PCMU", 8000, 1}},
838 {103, {"ISAC", 16000, 1}},
839 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840}
841
842// Test that we can decode OPUS with stereo = 0.
843TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700844 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 cricket::AudioRecvParameters parameters;
846 parameters.codecs.push_back(kIsacCodec);
847 parameters.codecs.push_back(kPcmuCodec);
848 parameters.codecs.push_back(kOpusCodec);
849 parameters.codecs[2].params["stereo"] = "0";
850 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800851 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700852 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
853 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
854 {{0, {"PCMU", 8000, 1}},
855 {103, {"ISAC", 16000, 1}},
856 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
859// Test that we can decode OPUS with stereo = 1.
860TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700861 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200862 cricket::AudioRecvParameters parameters;
863 parameters.codecs.push_back(kIsacCodec);
864 parameters.codecs.push_back(kPcmuCodec);
865 parameters.codecs.push_back(kOpusCodec);
866 parameters.codecs[2].params["stereo"] = "1";
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800868 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700869 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
870 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
871 {{0, {"PCMU", 8000, 1}},
872 {103, {"ISAC", 16000, 1}},
873 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874}
875
876// Test that changes to recv codecs are applied to all streams.
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
881 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800882 parameters.codecs.push_back(kTelephoneEventCodec1);
883 parameters.codecs.push_back(kTelephoneEventCodec2);
884 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 parameters.codecs[2].id = 126;
886 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700887 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
888 EXPECT_TRUE(AddRecvStream(ssrc));
889 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
890 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
891 {{0, {"PCMU", 8000, 1}},
892 {106, {"ISAC", 16000, 1}},
893 {126, {"telephone-event", 8000, 1}},
894 {107, {"telephone-event", 32000, 1}}})));
895 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
898TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700899 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200900 cricket::AudioRecvParameters parameters;
901 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800902 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
solenberg2100c0b2017-03-01 11:29:29 -0800905 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800906 ASSERT_EQ(1, dm.count(106));
907 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908}
909
910// Test that we can apply the same set of codecs again while playing.
911TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700912 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 cricket::AudioRecvParameters parameters;
914 parameters.codecs.push_back(kIsacCodec);
915 parameters.codecs.push_back(kCn16000Codec);
916 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700917 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
deadbeefcb383672017-04-26 16:28:42 -0700920 // Remapping a payload type to a different codec should fail.
921 parameters.codecs[0] = kOpusCodec;
922 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200923 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800924 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925}
926
927// Test that we can add a codec while playing.
928TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700929 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200930 cricket::AudioRecvParameters parameters;
931 parameters.codecs.push_back(kIsacCodec);
932 parameters.codecs.push_back(kCn16000Codec);
933 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700934 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200936 parameters.codecs.push_back(kOpusCodec);
937 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800938 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939}
940
deadbeefcb383672017-04-26 16:28:42 -0700941// Test that we accept adding the same codec with a different payload type.
942// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
943TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
944 EXPECT_TRUE(SetupRecvStream());
945 cricket::AudioRecvParameters parameters;
946 parameters.codecs.push_back(kIsacCodec);
947 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
948
949 ++parameters.codecs[0].id;
950 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
951}
952
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000956 // Test that when autobw is enabled, bitrate is kept as the default
957 // value. autobw is enabled for the following tests because the target
958 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959
960 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700961 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
963 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
ossu20a4b3f2017-04-27 02:08:52 -0700966 // opus, default bitrate == 32000 in mono.
967 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000970TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700971 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700974 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
975 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700976 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700979 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
980 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
981 // Rates above the max (510000) should be capped.
982 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983}
984
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000987
988 // Test that we can only set a maximum bitrate for a fixed-rate codec
989 // if it's bigger than the fixed rate.
990
991 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700992 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
995 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
996 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999}
1000
1001TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001002 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001003 const int kDesiredBitrate = 128000;
1004 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001005 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001006 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001008
1009 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001010 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001011
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001013}
1014
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015// Test that bitrate cannot be set for CBR codecs.
1016// Bitrate is ignored if it is higher than the fixed bitrate.
1017// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001018TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001019 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020
1021 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001022 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001023 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001024
1025 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001026 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001027 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001028
1029 send_parameters_.max_bandwidth_bps = 128;
1030 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001031 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032}
1033
skvlade0d46372016-04-07 22:59:22 -07001034// Test that the per-stream bitrate limit and the global
1035// bitrate limit both apply.
1036TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1037 EXPECT_TRUE(SetupSendStream());
1038
ossu20a4b3f2017-04-27 02:08:52 -07001039 // opus, default bitrate == 32000.
1040 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001041 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1042 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1043 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1044
1045 // CBR codecs allow both maximums to exceed the bitrate.
1046 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1047 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1049 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1050
1051 // CBR codecs don't allow per stream maximums to be too low.
1052 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1053 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1054}
1055
1056// Test that an attempt to set RtpParameters for a stream that does not exist
1057// fails.
1058TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1059 EXPECT_TRUE(SetupChannel());
1060 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001061 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001062 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1063
1064 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001066}
1067
1068TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001069 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001070 // This test verifies that setting RtpParameters succeeds only if
1071 // the structure contains exactly one encoding.
1072 // TODO(skvlad): Update this test when we start supporting setting parameters
1073 // for each encoding individually.
1074
1075 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001076 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001077 // Two or more encodings should result in failure.
1078 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001079 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001080 // Zero encodings should also fail.
1081 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001082 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001083}
1084
1085// Changing the SSRC through RtpParameters is not allowed.
1086TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1087 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001088 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001089 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001091}
1092
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001093// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001094// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1096 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001097 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001098 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001100 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001101 ASSERT_EQ(1u, parameters.encodings.size());
1102 ASSERT_TRUE(parameters.encodings[0].active);
1103 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001104 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1105 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001106
1107 // Now change it back to active and verify we resume sending.
1108 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001109 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1110 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001111}
1112
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001113// Test that SetRtpSendParameters configures the correct encoding channel for
1114// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001115TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1116 SetupForMultiSendStream();
1117 // Create send streams.
1118 for (uint32_t ssrc : kSsrcs4) {
1119 EXPECT_TRUE(
1120 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1121 }
1122 // Configure one stream to be limited by the stream config, another to be
1123 // limited by the global max, and the third one with no per-stream limit
1124 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001125 SetGlobalMaxBitrate(kOpusCodec, 32000);
1126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001128 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1129
ossu20a4b3f2017-04-27 02:08:52 -07001130 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1131 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1132 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001133
1134 // Remove the global cap; the streams should switch to their respective
1135 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001136 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001137 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1138 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1139 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001140}
1141
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001142// Test that GetRtpSendParameters returns the currently configured codecs.
1143TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001144 EXPECT_TRUE(SetupSendStream());
1145 cricket::AudioSendParameters parameters;
1146 parameters.codecs.push_back(kIsacCodec);
1147 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001148 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149
solenberg2100c0b2017-03-01 11:29:29 -08001150 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001152 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1153 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154}
1155
deadbeefcb443432016-12-12 11:12:36 -08001156// Test that GetRtpSendParameters returns an SSRC.
1157TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1158 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001159 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001160 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001161 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001162}
1163
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001164// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001165TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001166 EXPECT_TRUE(SetupSendStream());
1167 cricket::AudioSendParameters parameters;
1168 parameters.codecs.push_back(kIsacCodec);
1169 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001170 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001171
solenberg2100c0b2017-03-01 11:29:29 -08001172 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001173
1174 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001175 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001177 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001178 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1179 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001180}
1181
minyuececec102017-03-27 13:04:25 -07001182// Test that max_bitrate_bps in send stream config gets updated correctly when
1183// SetRtpSendParameters is called.
1184TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1185 webrtc::test::ScopedFieldTrials override_field_trials(
1186 "WebRTC-Audio-SendSideBwe/Enabled/");
1187 EXPECT_TRUE(SetupSendStream());
1188 cricket::AudioSendParameters send_parameters;
1189 send_parameters.codecs.push_back(kOpusCodec);
1190 SetSendParameters(send_parameters);
1191
1192 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1193 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1194 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1195
1196 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001197 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001198 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1199
1200 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1201 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1202}
1203
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001204// Test that GetRtpReceiveParameters returns the currently configured codecs.
1205TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1206 EXPECT_TRUE(SetupRecvStream());
1207 cricket::AudioRecvParameters parameters;
1208 parameters.codecs.push_back(kIsacCodec);
1209 parameters.codecs.push_back(kPcmuCodec);
1210 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1211
1212 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001213 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001214 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1215 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1216 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1217}
1218
deadbeefcb443432016-12-12 11:12:36 -08001219// Test that GetRtpReceiveParameters returns an SSRC.
1220TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1221 EXPECT_TRUE(SetupRecvStream());
1222 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001223 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001224 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001225 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001226}
1227
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001228// Test that if we set/get parameters multiple times, we get the same results.
1229TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1230 EXPECT_TRUE(SetupRecvStream());
1231 cricket::AudioRecvParameters parameters;
1232 parameters.codecs.push_back(kIsacCodec);
1233 parameters.codecs.push_back(kPcmuCodec);
1234 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1235
1236 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001237 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001238
1239 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001240 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001241
1242 // ... And this shouldn't change the params returned by
1243 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001244 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1245 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001246}
1247
deadbeef3bc15102017-04-20 19:25:07 -07001248// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1249// aren't signaled. It should return an empty "RtpEncodingParameters" when
1250// configured to receive an unsignaled stream and no packets have been received
1251// yet, and start returning the SSRC once a packet has been received.
1252TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1253 ASSERT_TRUE(SetupChannel());
1254 // Call necessary methods to configure receiving a default stream as
1255 // soon as it arrives.
1256 cricket::AudioRecvParameters parameters;
1257 parameters.codecs.push_back(kIsacCodec);
1258 parameters.codecs.push_back(kPcmuCodec);
1259 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1260
1261 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1262 // stream. Should return nothing.
1263 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1264
1265 // Set a sink for an unsignaled stream.
1266 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1267 // Value of "0" means "unsignaled stream".
1268 channel_->SetRawAudioSink(0, std::move(fake_sink));
1269
1270 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1271 // in this method means "unsignaled stream".
1272 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1273 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1274 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1275
1276 // Receive PCMU packet (SSRC=1).
1277 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1278
1279 // The |ssrc| member should still be unset.
1280 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1281 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1282 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1283}
1284
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285// Test that we apply codecs properly.
1286TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001287 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001288 cricket::AudioSendParameters parameters;
1289 parameters.codecs.push_back(kIsacCodec);
1290 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001291 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001292 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001293 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001294 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001295 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1296 EXPECT_EQ(96, send_codec_spec.payload_type);
1297 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1298 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1299 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001300 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001301 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001302}
1303
ossu20a4b3f2017-04-27 02:08:52 -07001304// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1305// AudioSendStream.
1306TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001307 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001308 cricket::AudioSendParameters parameters;
1309 parameters.codecs.push_back(kIsacCodec);
1310 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001311 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001312 parameters.codecs[0].id = 96;
1313 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001314 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001315 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001316 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001317 // Calling SetSendCodec again with same codec which is already set.
1318 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001319 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001320 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001321}
1322
ossu20a4b3f2017-04-27 02:08:52 -07001323// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1324// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001325
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001326// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001328 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001329 cricket::AudioSendParameters parameters;
1330 parameters.codecs.push_back(kOpusCodec);
1331 parameters.codecs[0].bitrate = 0;
1332 parameters.codecs[0].clockrate = 50000;
1333 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334}
1335
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001336// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001338 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 cricket::AudioSendParameters parameters;
1340 parameters.codecs.push_back(kOpusCodec);
1341 parameters.codecs[0].bitrate = 0;
1342 parameters.codecs[0].channels = 0;
1343 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001346// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
1352 parameters.codecs[0].channels = 0;
1353 parameters.codecs[0].params["stereo"] = "1";
1354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
1357// Test that if channel is 1 for opus and there's no stereo, we fail.
1358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].channels = 1;
1364 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365}
1366
1367// Test that if channel is 1 for opus and stereo=0, we fail.
1368TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001369 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 cricket::AudioSendParameters parameters;
1371 parameters.codecs.push_back(kOpusCodec);
1372 parameters.codecs[0].bitrate = 0;
1373 parameters.codecs[0].channels = 1;
1374 parameters.codecs[0].params["stereo"] = "0";
1375 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376}
1377
1378// Test that if channel is 1 for opus and stereo=1, we fail.
1379TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001380 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001381 cricket::AudioSendParameters parameters;
1382 parameters.codecs.push_back(kOpusCodec);
1383 parameters.codecs[0].bitrate = 0;
1384 parameters.codecs[0].channels = 1;
1385 parameters.codecs[0].params["stereo"] = "1";
1386 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387}
1388
ossu20a4b3f2017-04-27 02:08:52 -07001389// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001390TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001391 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 cricket::AudioSendParameters parameters;
1393 parameters.codecs.push_back(kOpusCodec);
1394 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001396 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397}
1398
ossu20a4b3f2017-04-27 02:08:52 -07001399// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001401 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 cricket::AudioSendParameters parameters;
1403 parameters.codecs.push_back(kOpusCodec);
1404 parameters.codecs[0].bitrate = 0;
1405 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001407 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408}
1409
ossu20a4b3f2017-04-27 02:08:52 -07001410// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001411TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001412 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 cricket::AudioSendParameters parameters;
1414 parameters.codecs.push_back(kOpusCodec);
1415 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001416 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001419 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001420
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001422 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001423 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001424}
1425
ossu20a4b3f2017-04-27 02:08:52 -07001426// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001427TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001428 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 cricket::AudioSendParameters parameters;
1430 parameters.codecs.push_back(kOpusCodec);
1431 parameters.codecs[0].bitrate = 0;
1432 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001433 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001434 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435}
1436
ossu20a4b3f2017-04-27 02:08:52 -07001437// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001439 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 cricket::AudioSendParameters parameters;
1441 parameters.codecs.push_back(kOpusCodec);
1442 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001443 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001444 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001445 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001446 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001447
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001449 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001450 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001451}
1452
ossu20a4b3f2017-04-27 02:08:52 -07001453// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001459 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001460 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1461 EXPECT_EQ(111, spec.payload_type);
1462 EXPECT_EQ(96000, spec.target_bitrate_bps);
1463 EXPECT_EQ("opus", spec.format.name);
1464 EXPECT_EQ(2, spec.format.num_channels);
1465 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466}
1467
ossu20a4b3f2017-04-27 02:08:52 -07001468// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001470 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 cricket::AudioSendParameters parameters;
1472 parameters.codecs.push_back(kOpusCodec);
1473 parameters.codecs[0].bitrate = 30000;
1474 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001475 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001476 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477}
1478
ossu20a4b3f2017-04-27 02:08:52 -07001479// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001485 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001486 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487}
1488
ossu20a4b3f2017-04-27 02:08:52 -07001489// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001491 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001492 cricket::AudioSendParameters parameters;
1493 parameters.codecs.push_back(kOpusCodec);
1494 parameters.codecs[0].bitrate = 30000;
1495 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001497 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001498}
1499
stefan13f1a0a2016-11-30 07:22:58 -08001500TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1501 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1502 200000);
1503}
1504
1505TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1506 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1507}
1508
1509TEST_F(WebRtcVoiceEngineTestFake,
1510 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1511 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1512}
1513
1514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1515 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1516}
1517
1518TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001519 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001520 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1521 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001522 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001523 SetSendParameters(send_parameters_);
1524 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1525 << "Setting max bitrate should keep previous min bitrate.";
1526 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1527 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001528 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001529}
1530
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001531// Test that we can enable NACK with opus as caller.
1532TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001533 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001534 cricket::AudioSendParameters parameters;
1535 parameters.codecs.push_back(kOpusCodec);
1536 parameters.codecs[0].AddFeedbackParam(
1537 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1538 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001539 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542}
1543
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001544// Test that we can enable NACK with opus as callee.
1545TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001546 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001547 cricket::AudioSendParameters parameters;
1548 parameters.codecs.push_back(kOpusCodec);
1549 parameters.codecs[0].AddFeedbackParam(
1550 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1551 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001554 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001556
1557 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001558 cricket::StreamParams::CreateLegacy(kSsrcX)));
1559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001560}
1561
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562// Test that we can enable NACK on receive streams.
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001564 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001565 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].AddFeedbackParam(
1569 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1570 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1572 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1575 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576}
1577
1578// Test that we can disable NACK.
1579TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001580 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001581 cricket::AudioSendParameters parameters;
1582 parameters.codecs.push_back(kOpusCodec);
1583 parameters.codecs[0].AddFeedbackParam(
1584 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1585 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001586 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001587 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 parameters.codecs.clear();
1590 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001591 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001592 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
1595// Test that we can disable NACK on receive streams.
1596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001597 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 cricket::AudioSendParameters parameters;
1600 parameters.codecs.push_back(kOpusCodec);
1601 parameters.codecs[0].AddFeedbackParam(
1602 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1603 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001604 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001605 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1606 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 parameters.codecs.clear();
1609 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001611 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1612 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613}
1614
1615// Test that NACK is enabled on a new receive stream.
1616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001617 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001618 cricket::AudioSendParameters parameters;
1619 parameters.codecs.push_back(kIsacCodec);
1620 parameters.codecs.push_back(kCn16000Codec);
1621 parameters.codecs[0].AddFeedbackParam(
1622 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1623 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001625 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626
solenberg2100c0b2017-03-01 11:29:29 -08001627 EXPECT_TRUE(AddRecvStream(kSsrcY));
1628 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1629 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1630 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001631}
1632
stefanba4c0e42016-02-04 04:12:24 -08001633TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001634 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001635 cricket::AudioSendParameters send_parameters;
1636 send_parameters.codecs.push_back(kOpusCodec);
1637 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001638 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001639
1640 cricket::AudioRecvParameters recv_parameters;
1641 recv_parameters.codecs.push_back(kIsacCodec);
1642 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001643 EXPECT_TRUE(AddRecvStream(kSsrcX));
1644 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001645 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001646 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001647
ossudedfd282016-06-14 07:12:39 -07001648 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001649 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001650 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001651 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001652 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001653}
1654
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001655// Test that we can switch back and forth between Opus and ISAC with CN.
1656TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001657 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001658
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001659 cricket::AudioSendParameters opus_parameters;
1660 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001661 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001662 {
ossu20a4b3f2017-04-27 02:08:52 -07001663 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1664 EXPECT_EQ(111, spec.payload_type);
1665 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001666 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001668 cricket::AudioSendParameters isac_parameters;
1669 isac_parameters.codecs.push_back(kIsacCodec);
1670 isac_parameters.codecs.push_back(kCn16000Codec);
1671 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(103, spec.payload_type);
1676 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001677 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678
solenberg059fb442016-10-26 05:12:24 -07001679 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001680 {
ossu20a4b3f2017-04-27 02:08:52 -07001681 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1682 EXPECT_EQ(111, spec.payload_type);
1683 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001684 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685}
1686
1687// Test that we handle various ways of specifying bitrate.
1688TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001689 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001690 cricket::AudioSendParameters parameters;
1691 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001693 {
ossu20a4b3f2017-04-27 02:08:52 -07001694 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1695 EXPECT_EQ(103, spec.payload_type);
1696 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1697 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001698 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001699
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001700 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001702 {
ossu20a4b3f2017-04-27 02:08:52 -07001703 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1704 EXPECT_EQ(103, spec.payload_type);
1705 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1706 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001707 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001708 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001710 {
ossu20a4b3f2017-04-27 02:08:52 -07001711 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1712 EXPECT_EQ(103, spec.payload_type);
1713 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1714 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001715 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001718 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001719 {
ossu20a4b3f2017-04-27 02:08:52 -07001720 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1721 EXPECT_EQ(0, spec.payload_type);
1722 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1723 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001724 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001725
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001726 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001727 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001728 {
ossu20a4b3f2017-04-27 02:08:52 -07001729 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1730 EXPECT_EQ(0, spec.payload_type);
1731 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1732 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 parameters.codecs[0] = kOpusCodec;
1736 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001738 {
ossu20a4b3f2017-04-27 02:08:52 -07001739 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1740 EXPECT_EQ(111, spec.payload_type);
1741 EXPECT_STREQ("opus", spec.format.name.c_str());
1742 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001743 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744}
1745
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001746// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001747TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001748 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters parameters;
1750 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001751}
1752
1753// Test that we can set send codecs even with telephone-event codec as the first
1754// one on the list.
1755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001756 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001758 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001759 parameters.codecs.push_back(kIsacCodec);
1760 parameters.codecs.push_back(kPcmuCodec);
1761 parameters.codecs[0].id = 98; // DTMF
1762 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001763 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001764 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1765 EXPECT_EQ(96, spec.payload_type);
1766 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001767 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001768}
1769
solenberg31642aa2016-03-14 08:00:37 -07001770// Test that payload type range is limited for telephone-event codec.
1771TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001772 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001773 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001774 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001775 parameters.codecs.push_back(kIsacCodec);
1776 parameters.codecs[0].id = 0; // DTMF
1777 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001778 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001779 EXPECT_TRUE(channel_->CanInsertDtmf());
1780 parameters.codecs[0].id = 128; // DTMF
1781 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1782 EXPECT_FALSE(channel_->CanInsertDtmf());
1783 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001784 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001785 EXPECT_TRUE(channel_->CanInsertDtmf());
1786 parameters.codecs[0].id = -1; // DTMF
1787 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1788 EXPECT_FALSE(channel_->CanInsertDtmf());
1789}
1790
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001791// Test that we can set send codecs even with CN codec as the first
1792// one on the list.
1793TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001794 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 cricket::AudioSendParameters parameters;
1796 parameters.codecs.push_back(kCn16000Codec);
1797 parameters.codecs.push_back(kIsacCodec);
1798 parameters.codecs.push_back(kPcmuCodec);
1799 parameters.codecs[0].id = 98; // wideband CN
1800 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001801 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_EQ(96, send_codec_spec.payload_type);
1804 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001805 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806}
1807
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001808// Test that we set VAD and DTMF types correctly as caller.
1809TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001810 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 cricket::AudioSendParameters parameters;
1812 parameters.codecs.push_back(kIsacCodec);
1813 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 parameters.codecs.push_back(kCn16000Codec);
1816 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001817 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs[0].id = 96;
1819 parameters.codecs[2].id = 97; // wideband CN
1820 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001821 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001822 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1823 EXPECT_EQ(96, send_codec_spec.payload_type);
1824 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1825 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001826 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001827 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001828}
1829
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001830// Test that we set VAD and DTMF types correctly as callee.
1831TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001832 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 cricket::AudioSendParameters parameters;
1834 parameters.codecs.push_back(kIsacCodec);
1835 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001836 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 parameters.codecs.push_back(kCn16000Codec);
1838 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001839 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 parameters.codecs[0].id = 96;
1841 parameters.codecs[2].id = 97; // wideband CN
1842 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001843 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001844 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001845 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001846
ossu20a4b3f2017-04-27 02:08:52 -07001847 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1848 EXPECT_EQ(96, send_codec_spec.payload_type);
1849 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1850 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001851 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001852 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001853}
1854
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001855// Test that we only apply VAD if we have a CN codec that matches the
1856// send codec clockrate.
1857TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001858 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001860 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001861 parameters.codecs.push_back(kIsacCodec);
1862 parameters.codecs.push_back(kCn16000Codec);
1863 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001865 {
ossu20a4b3f2017-04-27 02:08:52 -07001866 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1867 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1868 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001869 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001870 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001871 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001872 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001874 {
ossu20a4b3f2017-04-27 02:08:52 -07001875 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1876 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001877 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001878 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001879 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001881 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001882 {
ossu20a4b3f2017-04-27 02:08:52 -07001883 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1884 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1885 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001886 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001887 }
Brave Yao5225dd82015-03-26 07:39:19 +08001888 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001889 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001890 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001891 {
ossu20a4b3f2017-04-27 02:08:52 -07001892 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1893 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001894 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001895 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896}
1897
1898// Test that we perform case-insensitive matching of codec names.
1899TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001901 cricket::AudioSendParameters parameters;
1902 parameters.codecs.push_back(kIsacCodec);
1903 parameters.codecs.push_back(kPcmuCodec);
1904 parameters.codecs.push_back(kCn16000Codec);
1905 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001906 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001907 parameters.codecs[0].name = "iSaC";
1908 parameters.codecs[0].id = 96;
1909 parameters.codecs[2].id = 97; // wideband CN
1910 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001912 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1913 EXPECT_EQ(96, send_codec_spec.payload_type);
1914 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1915 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001916 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001917 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001918}
1919
stefanba4c0e42016-02-04 04:12:24 -08001920class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1921 public:
1922 WebRtcVoiceEngineWithSendSideBweTest()
1923 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1924};
1925
1926TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1927 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001928 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001929 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001930 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1931 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1932 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001933 extension.id);
1934 return;
1935 }
1936 }
1937 FAIL() << "Transport sequence number extension not in header-extension list.";
1938}
1939
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001940// Test support for audio level header extension.
1941TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001942 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001943}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001944TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001945 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001946}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001947
solenbergd4adce42016-11-17 06:26:52 -08001948// Test support for transport sequence number header extension.
1949TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1950 TestSetSendRtpHeaderExtensions(
1951 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001952}
solenbergd4adce42016-11-17 06:26:52 -08001953TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1954 TestSetRecvRtpHeaderExtensions(
1955 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001956}
1957
solenberg1ac56142015-10-13 03:58:19 -07001958// Test that we can create a channel and start sending on it.
1959TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001960 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(send_parameters_);
1962 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001963 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001964 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001965 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001966}
1967
1968// Test that a channel will send if and only if it has a source and is enabled
1969// for sending.
1970TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001973 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001974 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001975 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1976 SetAudioSend(kSsrcX, true, &fake_source_);
1977 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1978 SetAudioSend(kSsrcX, true, nullptr);
1979 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001980}
1981
solenberg94218532016-06-16 10:53:22 -07001982// Test that a channel is muted/unmuted.
1983TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1984 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001985 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1987 SetAudioSend(kSsrcX, true, nullptr);
1988 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1989 SetAudioSend(kSsrcX, false, nullptr);
1990 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001991}
1992
solenberg6d6e7c52016-04-13 09:07:30 -07001993// Test that SetSendParameters() does not alter a stream's send state.
1994TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1995 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001996 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001997
1998 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001999 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002000 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002001
2002 // Changing RTP header extensions will recreate the AudioSendStream.
2003 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002004 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002005 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002006 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002007
2008 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002009 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002010 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002011
2012 // Changing RTP header extensions will recreate the AudioSendStream.
2013 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002014 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002015 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002016}
2017
solenberg1ac56142015-10-13 03:58:19 -07002018// Test that we can create a channel and start playing out on it.
2019TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002020 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002021 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002022 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002023 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002024 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002025 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002026}
2027
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002028// Test that we can add and remove send streams.
2029TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2030 SetupForMultiSendStream();
2031
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002032 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002033 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034
solenbergc96df772015-10-21 13:01:53 -07002035 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002037 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002038 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002040 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041 }
tfarina5237aaf2015-11-10 23:44:30 -08002042 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043
solenbergc96df772015-10-21 13:01:53 -07002044 // Delete the send streams.
2045 for (uint32_t ssrc : kSsrcs4) {
2046 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002047 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002048 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049 }
solenbergc96df772015-10-21 13:01:53 -07002050 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051}
2052
2053// Test SetSendCodecs correctly configure the codecs in all send streams.
2054TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2055 SetupForMultiSendStream();
2056
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002057 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002058 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002060 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 }
2062
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002063 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002064 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002065 parameters.codecs.push_back(kIsacCodec);
2066 parameters.codecs.push_back(kCn16000Codec);
2067 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069
2070 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002071 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002072 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2073 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002074 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2075 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2076 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002077 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002078 }
2079
minyue7a973442016-10-20 03:27:12 -07002080 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002081 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002082 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002083 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002084 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2085 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002086 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2087 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002088 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
2090}
2091
2092// Test we can SetSend on all send streams correctly.
2093TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2094 SetupForMultiSendStream();
2095
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002096 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002097 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002098 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002099 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002100 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002101 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102 }
2103
2104 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002105 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002106 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002108 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 }
2110
2111 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002112 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002113 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002115 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002116 }
2117}
2118
2119// Test we can set the correct statistics on all send streams.
2120TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2121 SetupForMultiSendStream();
2122
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002124 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002126 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127 }
solenberg85a04962015-10-27 03:35:21 -07002128
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002129 // Create a receive stream to check that none of the send streams end up in
2130 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002131 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002132
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002133 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002134 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002135 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002136 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002137
solenberg85a04962015-10-27 03:35:21 -07002138 // Check stats for the added streams.
2139 {
2140 cricket::VoiceMediaInfo info;
2141 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002142
solenberg85a04962015-10-27 03:35:21 -07002143 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002144 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002145 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002146 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002147 }
hbos1acfbd22016-11-17 23:43:29 -08002148 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002149
2150 // We have added one receive stream. We should see empty stats.
2151 EXPECT_EQ(info.receivers.size(), 1u);
2152 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002153 }
solenberg1ac56142015-10-13 03:58:19 -07002154
solenberg2100c0b2017-03-01 11:29:29 -08002155 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002156 {
2157 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002158 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002159 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002160 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002161 EXPECT_EQ(0u, info.receivers.size());
2162 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002163
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002164 // Deliver a new packet - a default receive stream should be created and we
2165 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002166 {
2167 cricket::VoiceMediaInfo info;
2168 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2169 SetAudioReceiveStreamStats();
2170 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002171 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002172 EXPECT_EQ(1u, info.receivers.size());
2173 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002174 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002175 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002176}
2177
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002178// Test that we can add and remove receive streams, and do proper send/playout.
2179// We can receive on multiple streams while sending one stream.
2180TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002181 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002182
solenberg1ac56142015-10-13 03:58:19 -07002183 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002184 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002185 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002186
solenberg1ac56142015-10-13 03:58:19 -07002187 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002188 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002189 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002190 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002191
solenberg1ac56142015-10-13 03:58:19 -07002192 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002193 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194
2195 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002196 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2197 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2198 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002199
2200 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002201 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002202 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002203
2204 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002205 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002206 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2207 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002208
aleloi84ef6152016-08-04 05:28:21 -07002209 // Restart playout and make sure recv streams are played out.
2210 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002211 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2212 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002213
aleloi84ef6152016-08-04 05:28:21 -07002214 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002215 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2216 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002217}
2218
wu@webrtc.org97077a32013-10-25 21:18:33 +00002219TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002220 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002221 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2222 .Times(1)
2223 .WillRepeatedly(Return(false));
2224 EXPECT_CALL(adm_, SetAGC(true)).Times(1).WillRepeatedly(Return(0));
2225 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2226 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002227 send_parameters_.options.tx_agc_target_dbov = 3;
2228 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2229 send_parameters_.options.tx_agc_limiter = true;
2230 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002231 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2232 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2233 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002234 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002235}
2236
minyue6b825df2016-10-31 04:08:32 -07002237TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2238 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002239 send_parameters_.options.audio_network_adaptor = true;
2240 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002241 SetSendParameters(send_parameters_);
2242 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002243 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002244}
2245
2246TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2247 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002248 send_parameters_.options.audio_network_adaptor = true;
2249 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002250 SetSendParameters(send_parameters_);
2251 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002252 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002253 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002254 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002255 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002256 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002257}
2258
2259TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2260 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002261 send_parameters_.options.audio_network_adaptor = true;
2262 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002263 SetSendParameters(send_parameters_);
2264 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002265 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002266 const int initial_num = call_.GetNumCreatedSendStreams();
2267 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002268 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002269 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2270 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002271 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002272 // AudioSendStream not expected to be recreated.
2273 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2274 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002275 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002276}
2277
michaelt6672b262017-01-11 10:17:59 -08002278class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2279 : public WebRtcVoiceEngineTestFake {
2280 public:
2281 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2282 : WebRtcVoiceEngineTestFake(
2283 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2284 "Enabled/") {}
2285};
2286
2287TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2288 EXPECT_TRUE(SetupSendStream());
2289 cricket::AudioSendParameters parameters;
2290 parameters.codecs.push_back(kOpusCodec);
2291 SetSendParameters(parameters);
2292 const int initial_num = call_.GetNumCreatedSendStreams();
2293 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2294
2295 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2296 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002297 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2298 constexpr int kMinOverheadBps =
2299 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002300
2301 constexpr int kOpusMinBitrateBps = 6000;
2302 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002303 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002304 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002305 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002306 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002307
Oskar Sundbom78807582017-11-16 11:09:55 +01002308 parameters.options.audio_network_adaptor = true;
2309 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002310 SetSendParameters(parameters);
2311
ossu11bfc532017-02-16 05:37:06 -08002312 constexpr int kMinOverheadWithAnaBps =
2313 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002314
2315 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002316 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002317
minyuececec102017-03-27 13:04:25 -07002318 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002319 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002320}
2321
minyuececec102017-03-27 13:04:25 -07002322// This test is similar to
2323// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2324// additional field trial.
2325TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2326 SetRtpSendParameterUpdatesMaxBitrate) {
2327 EXPECT_TRUE(SetupSendStream());
2328 cricket::AudioSendParameters send_parameters;
2329 send_parameters.codecs.push_back(kOpusCodec);
2330 SetSendParameters(send_parameters);
2331
2332 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2333 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2334 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2335
2336 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002337 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002338 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2339
2340 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2341#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2342 constexpr int kMinOverhead = 3333;
2343#else
2344 constexpr int kMinOverhead = 6666;
2345#endif
2346 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2347}
2348
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002350// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002351TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002352 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002353 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002354}
2355
2356TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2357 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002358 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002359 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002360 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002361 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002362 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002363 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002364 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365
solenberg85a04962015-10-27 03:35:21 -07002366 // Check stats for the added streams.
2367 {
2368 cricket::VoiceMediaInfo info;
2369 EXPECT_EQ(true, channel_->GetStats(&info));
2370
2371 // We have added one send stream. We should see the stats we've set.
2372 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002373 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002374 // We have added one receive stream. We should see empty stats.
2375 EXPECT_EQ(info.receivers.size(), 1u);
2376 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2377 }
solenberg1ac56142015-10-13 03:58:19 -07002378
solenberg566ef242015-11-06 15:34:49 -08002379 // Start sending - this affects some reported stats.
2380 {
2381 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002382 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002383 EXPECT_EQ(true, channel_->GetStats(&info));
2384 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002385 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002386 }
2387
solenberg2100c0b2017-03-01 11:29:29 -08002388 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002389 {
2390 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002391 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002392 EXPECT_EQ(true, channel_->GetStats(&info));
2393 EXPECT_EQ(1u, info.senders.size());
2394 EXPECT_EQ(0u, info.receivers.size());
2395 }
solenberg1ac56142015-10-13 03:58:19 -07002396
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002397 // Deliver a new packet - a default receive stream should be created and we
2398 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002399 {
2400 cricket::VoiceMediaInfo info;
2401 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2402 SetAudioReceiveStreamStats();
2403 EXPECT_EQ(true, channel_->GetStats(&info));
2404 EXPECT_EQ(1u, info.senders.size());
2405 EXPECT_EQ(1u, info.receivers.size());
2406 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002407 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002408 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409}
2410
2411// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002412// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002414 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002415 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2416 EXPECT_TRUE(AddRecvStream(kSsrcY));
2417 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420// Test that the local SSRC is the same on sending and receiving channels if the
2421// receive channel is created before the send channel.
2422TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002424 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002426 cricket::StreamParams::CreateLegacy(kSsrcX)));
2427 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2428 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429}
2430
2431// Test that we can properly receive packets.
2432TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002433 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002434 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002436
2437 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2438 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439}
2440
2441// Test that we can properly receive packets on multiple streams.
2442TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002443 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002444 const uint32_t ssrc1 = 1;
2445 const uint32_t ssrc2 = 2;
2446 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002447 EXPECT_TRUE(AddRecvStream(ssrc1));
2448 EXPECT_TRUE(AddRecvStream(ssrc2));
2449 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002451 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002452 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002454 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 }
mflodman3d7db262016-04-29 00:57:13 -07002456
2457 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2458 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2459 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2460
2461 EXPECT_EQ(s1.received_packets(), 0);
2462 EXPECT_EQ(s2.received_packets(), 0);
2463 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002464
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002466 EXPECT_EQ(s1.received_packets(), 0);
2467 EXPECT_EQ(s2.received_packets(), 0);
2468 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002469
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002471 EXPECT_EQ(s1.received_packets(), 1);
2472 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2473 EXPECT_EQ(s2.received_packets(), 0);
2474 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002475
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002477 EXPECT_EQ(s1.received_packets(), 1);
2478 EXPECT_EQ(s2.received_packets(), 1);
2479 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2480 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002481
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002483 EXPECT_EQ(s1.received_packets(), 1);
2484 EXPECT_EQ(s2.received_packets(), 1);
2485 EXPECT_EQ(s3.received_packets(), 1);
2486 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002487
mflodman3d7db262016-04-29 00:57:13 -07002488 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2489 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2490 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491}
2492
solenberg2100c0b2017-03-01 11:29:29 -08002493// Test that receiving on an unsignaled stream works (a stream is created).
2494TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002495 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002496 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2497
solenberg7e63ef02015-11-20 00:19:43 -08002498 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002499
2500 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002501 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2502 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002503}
2504
solenberg2100c0b2017-03-01 11:29:29 -08002505// Test that receiving N unsignaled stream works (streams will be created), and
2506// that packets are forwarded to them all.
2507TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002508 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002509 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002510 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2511
solenberg2100c0b2017-03-01 11:29:29 -08002512 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002513 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002514 rtc::SetBE32(&packet[8], ssrc);
2515 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002516
solenberg2100c0b2017-03-01 11:29:29 -08002517 // Verify we have one new stream for each loop iteration.
2518 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002519 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2520 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002521 }
mflodman3d7db262016-04-29 00:57:13 -07002522
solenberg2100c0b2017-03-01 11:29:29 -08002523 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002524 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002525 rtc::SetBE32(&packet[8], ssrc);
2526 DeliverPacket(packet, sizeof(packet));
2527
solenbergebb349d2017-03-13 05:46:15 -07002528 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002529 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2530 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2531 }
2532
2533 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2534 constexpr uint32_t kAnotherSsrc = 667;
2535 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002536 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002537
2538 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002539 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002540 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002541 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002542 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2543 EXPECT_EQ(2, streams[i]->received_packets());
2544 }
2545 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2546 EXPECT_EQ(1, streams[i]->received_packets());
2547 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002548 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002549}
2550
solenberg2100c0b2017-03-01 11:29:29 -08002551// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002552// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002553TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002554 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002555 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002556 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2557
2558 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002559 const uint32_t signaled_ssrc = 1;
2560 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002561 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002562 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002563 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2564 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002565 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002566
2567 // Note that the first unknown SSRC cannot be 0, because we only support
2568 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002569 const uint32_t unsignaled_ssrc = 7011;
2570 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2573 packet, sizeof(packet)));
2574 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2575
2576 DeliverPacket(packet, sizeof(packet));
2577 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2578
2579 rtc::SetBE32(&packet[8], signaled_ssrc);
2580 DeliverPacket(packet, sizeof(packet));
2581 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2582 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002583}
2584
solenberg4904fb62017-02-17 12:01:14 -08002585// Two tests to verify that adding a receive stream with the same SSRC as a
2586// previously added unsignaled stream will only recreate underlying stream
2587// objects if the stream parameters have changed.
2588TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2589 EXPECT_TRUE(SetupChannel());
2590
2591 // Spawn unsignaled stream with SSRC=1.
2592 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2593 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2594 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2595 sizeof(kPcmuFrame)));
2596
2597 // Verify that the underlying stream object in Call is not recreated when a
2598 // stream with SSRC=1 is added.
2599 const auto& streams = call_.GetAudioReceiveStreams();
2600 EXPECT_EQ(1, streams.size());
2601 int audio_receive_stream_id = streams.front()->id();
2602 EXPECT_TRUE(AddRecvStream(1));
2603 EXPECT_EQ(1, streams.size());
2604 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2605}
2606
2607TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2608 EXPECT_TRUE(SetupChannel());
2609
2610 // Spawn unsignaled stream with SSRC=1.
2611 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2612 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2613 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2614 sizeof(kPcmuFrame)));
2615
2616 // Verify that the underlying stream object in Call *is* recreated when a
2617 // stream with SSRC=1 is added, and which has changed stream parameters.
2618 const auto& streams = call_.GetAudioReceiveStreams();
2619 EXPECT_EQ(1, streams.size());
2620 int audio_receive_stream_id = streams.front()->id();
2621 cricket::StreamParams stream_params;
2622 stream_params.ssrcs.push_back(1);
2623 stream_params.sync_label = "sync_label";
2624 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2625 EXPECT_EQ(1, streams.size());
2626 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2627}
2628
solenberg0a617e22015-10-20 15:49:38 -07002629// Test that we properly handle failures to add a receive stream.
2630TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002631 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002632 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002633 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002634}
2635
solenberg0a617e22015-10-20 15:49:38 -07002636// Test that we properly handle failures to add a send stream.
2637TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002638 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002639 voe_.set_fail_create_channel(true);
2640 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2641}
2642
solenberg1ac56142015-10-13 03:58:19 -07002643// Test that AddRecvStream creates new stream.
2644TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002645 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002646 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002647 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002648 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002649}
2650
2651// Test that after adding a recv stream, we do not decode more codecs than
2652// those previously passed into SetRecvCodecs.
2653TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002654 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002655 cricket::AudioRecvParameters parameters;
2656 parameters.codecs.push_back(kIsacCodec);
2657 parameters.codecs.push_back(kPcmuCodec);
2658 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002659 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002660 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2661 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2662 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663}
2664
2665// Test that we properly clean up any streams that were added, even if
2666// not explicitly removed.
2667TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002668 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002669 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002670 EXPECT_TRUE(AddRecvStream(1));
2671 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002672 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2673 delete channel_;
2674 channel_ = NULL;
2675 EXPECT_EQ(0, voe_.GetNumChannels());
2676}
2677
wu@webrtc.org78187522013-10-07 23:32:02 +00002678TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002679 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002680 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002681}
2682
2683TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002684 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002685 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002686 // Manually delete channel to simulate a failure.
2687 int channel = voe_.GetLastChannel();
2688 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2689 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002690 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002691 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002692 EXPECT_NE(channel, new_channel);
2693 // The last created channel is deleted too.
2694 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002695}
2696
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002697// Test the InsertDtmf on default send stream as caller.
2698TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002699 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700}
2701
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002702// Test the InsertDtmf on default send stream as callee
2703TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002704 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002705}
2706
2707// Test the InsertDtmf on specified send stream as caller.
2708TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002709 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002710}
2711
2712// Test the InsertDtmf on specified send stream as callee.
2713TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002714 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715}
2716
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002717TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002718 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002719 EXPECT_CALL(adm_,
2720 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2721 EXPECT_CALL(adm_,
2722 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2723 EXPECT_CALL(adm_,
2724 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002725
solenberg246b8172015-12-08 09:50:23 -08002726 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2727 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002728
solenberg246b8172015-12-08 09:50:23 -08002729 // Nothing set in AudioOptions, so everything should be as default.
2730 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002731 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002732 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002733 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2734 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735
2736 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002737 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2738 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002739 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002740 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002741
2742 // Turn echo cancellation back on, with settings, and make sure
2743 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002744 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2745 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002746 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002747 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002749 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2750 // control.
solenberg76377c52017-02-21 00:54:31 -08002751 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2752 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002753 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002754 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002755
2756 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002757 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2758 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002759 send_parameters_.options.delay_agnostic_aec = false;
2760 send_parameters_.options.extended_filter_aec = false;
2761 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002762 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002763
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002764 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002765 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2766 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002767 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002768 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002769
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002774 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002775 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002776 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002777 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002778
2779 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002780 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2781 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002783 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002784 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002785 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002786 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002787
2788 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002789 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002792 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002793 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002794 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002795 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2797 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002798 send_parameters_.options.noise_suppression = false;
2799 send_parameters_.options.highpass_filter = false;
2800 send_parameters_.options.typing_detection = false;
2801 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002802 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002803 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804
solenberg1ac56142015-10-13 03:58:19 -07002805 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002806 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2807 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2808 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002809 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002810 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002811 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002812 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2814 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002815 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816}
2817
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002818TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002819 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002820 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002821 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002822 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002823 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002824 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002825 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002826 EXPECT_CALL(adm_,
2827 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2828 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2829 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002830 webrtc::AudioProcessing::Config apm_config;
2831 EXPECT_CALL(*apm_, GetConfig())
2832 .Times(10)
2833 .WillRepeatedly(ReturnPointee(&apm_config));
2834 EXPECT_CALL(*apm_, ApplyConfig(_))
2835 .Times(10)
2836 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002837 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002838
kwiberg686a8ef2016-02-26 03:00:35 -08002839 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002840 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002841 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002842 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002843 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002844 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002845
2846 // Have to add a stream to make SetSend work.
2847 cricket::StreamParams stream1;
2848 stream1.ssrcs.push_back(1);
2849 channel1->AddSendStream(stream1);
2850 cricket::StreamParams stream2;
2851 stream2.ssrcs.push_back(2);
2852 channel2->AddSendStream(stream2);
2853
2854 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002855 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002856 parameters_options_all.options.echo_cancellation = true;
2857 parameters_options_all.options.auto_gain_control = true;
2858 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002859 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2860 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2861 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002862 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002863 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002864 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002865 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002866 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002867 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002868 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002869 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002870
2871 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002872 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002873 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002877 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002878 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002879 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002880 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002881 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002882 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002883 expected_options.echo_cancellation = true;
2884 expected_options.auto_gain_control = true;
2885 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002886 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002887
2888 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002889 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002890 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002891 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002894 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002896 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002898 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002899 expected_options.echo_cancellation = true;
2900 expected_options.auto_gain_control = false;
2901 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002902 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002903
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2905 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2906 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002907 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002908 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002909 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002910 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002911 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002916 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002917 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002920 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921
solenberg76377c52017-02-21 00:54:31 -08002922 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2923 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002925 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002926 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002927 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002928 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002929 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002931 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2933 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002934 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2935 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002936 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2937 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2938 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002941 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002942 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002943 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002944 expected_options.echo_cancellation = true;
2945 expected_options.auto_gain_control = false;
2946 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002947 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002948}
2949
wu@webrtc.orgde305012013-10-31 15:40:38 +00002950// This test verifies DSCP settings are properly applied on voice media channel.
2951TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002952 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002953 cricket::FakeNetworkInterface network_interface;
2954 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002955 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002956
peahb1c9d1d2017-07-25 15:45:24 -07002957 webrtc::AudioProcessing::Config apm_config;
2958 EXPECT_CALL(*apm_, GetConfig())
2959 .Times(3)
2960 .WillRepeatedly(ReturnPointee(&apm_config));
2961 EXPECT_CALL(*apm_, ApplyConfig(_))
2962 .Times(3)
2963 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002964 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002965
solenbergbc37fc82016-04-04 09:54:44 -07002966 channel.reset(
2967 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002968 channel->SetInterface(&network_interface);
2969 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2970 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2971
2972 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002973 channel.reset(
2974 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002975 channel->SetInterface(&network_interface);
2976 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2977
2978 // Verify that setting the option to false resets the
2979 // DiffServCodePoint.
2980 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002981 channel.reset(
2982 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002983 channel->SetInterface(&network_interface);
2984 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2985 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2986
2987 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002988}
2989
solenberg1ac56142015-10-13 03:58:19 -07002990TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002991 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992 cricket::WebRtcVoiceMediaChannel* media_channel =
2993 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002994 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002995 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002996 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002997 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2998 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2999 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003000 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003001 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003002}
3003
solenberg1ac56142015-10-13 03:58:19 -07003004TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003005 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003007 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3008 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3009 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003010 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003011 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003012 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3013 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003014 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003015 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003016 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003017 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018}
3019
solenberg4bac9c52015-10-09 02:32:53 -07003020TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003021 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003022 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003024 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003026 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3027 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3028 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003029}
3030
solenberg2100c0b2017-03-01 11:29:29 -08003031TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003032 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003033
3034 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003035 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003036 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3037
3038 // Should remember the volume "2" which will be set on new unsignaled streams,
3039 // and also set the gain to 2 on existing unsignaled streams.
3040 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3041 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3042
3043 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3044 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3045 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3046 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3047 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3048 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3049
3050 // Setting gain with SSRC=0 should affect all unsignaled streams.
3051 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003052 if (kMaxUnsignaledRecvStreams > 1) {
3053 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3054 }
solenberg2100c0b2017-03-01 11:29:29 -08003055 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3056
3057 // Setting gain on an individual stream affects only that.
3058 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003059 if (kMaxUnsignaledRecvStreams > 1) {
3060 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3061 }
solenberg2100c0b2017-03-01 11:29:29 -08003062 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003063}
3064
pbos8fc7fa72015-07-15 08:02:58 -07003065TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003066 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003067 const std::string kSyncLabel = "AvSyncLabel";
3068
solenbergff976312016-03-30 23:28:51 -07003069 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003070 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3071 sp.sync_label = kSyncLabel;
3072 // Creating two channels to make sure that sync label is set properly for both
3073 // the default voice channel and following ones.
3074 EXPECT_TRUE(channel_->AddRecvStream(sp));
3075 sp.ssrcs[0] += 1;
3076 EXPECT_TRUE(channel_->AddRecvStream(sp));
3077
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003078 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003079 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003080 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003081 << "SyncGroup should be set based on sync_label";
3082 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003084 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003085}
3086
solenberg3a941542015-11-16 07:34:50 -08003087// TODO(solenberg): Remove, once recv streams are configured through Call.
3088// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003089TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003090 // Test that setting the header extensions results in the expected state
3091 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003092 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093 ssrcs.push_back(223);
3094 ssrcs.push_back(224);
3095
solenbergff976312016-03-30 23:28:51 -07003096 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003097 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003098 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003099 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 cricket::StreamParams::CreateLegacy(ssrc)));
3101 }
3102
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003103 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003104 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003105 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003106 EXPECT_NE(nullptr, s);
3107 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3108 }
3109
3110 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003111 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003112 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003113 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003114 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003115 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003116 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003117 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003118 EXPECT_NE(nullptr, s);
3119 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003120 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3121 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003122 for (const auto& s_ext : s_exts) {
3123 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003124 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 }
3126 }
3127 }
3128 }
3129
3130 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003131 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003132 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003133 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134 EXPECT_NE(nullptr, s);
3135 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3136 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003137}
3138
3139TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3140 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003141 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003142 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 static const unsigned char kRtcp[] = {
3144 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3145 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3148 };
jbaucheec21bd2016-03-20 06:15:43 -07003149 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003150
solenbergff976312016-03-30 23:28:51 -07003151 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003152 cricket::WebRtcVoiceMediaChannel* media_channel =
3153 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003154 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155 EXPECT_TRUE(media_channel->AddRecvStream(
3156 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3157
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003158 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003159 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003160 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003161 EXPECT_EQ(0, s->received_packets());
3162 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3163 EXPECT_EQ(1, s->received_packets());
3164 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3165 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003166}
Minyue2013aec2015-05-13 14:14:42 +02003167
solenberg0a617e22015-10-20 15:49:38 -07003168// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003169// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003170TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003171 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003172 EXPECT_TRUE(AddRecvStream(kSsrcY));
3173 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003174 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003175 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3176 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3177 EXPECT_TRUE(AddRecvStream(kSsrcW));
3178 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003179}
3180
solenberg7602aab2016-11-14 11:30:07 -08003181TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3182 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003183 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003184 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003185 cricket::StreamParams::CreateLegacy(kSsrcY)));
3186 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3187 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3188 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003189 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003190 cricket::StreamParams::CreateLegacy(kSsrcW)));
3191 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3192 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003193}
stefan658910c2015-09-03 05:48:32 -07003194
deadbeef884f5852016-01-15 09:20:04 -08003195TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003196 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003197 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3198 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003199
3200 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003201 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3202 EXPECT_TRUE(AddRecvStream(kSsrcX));
3203 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003204
3205 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003206 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3207 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003208
3209 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003210 channel_->SetRawAudioSink(kSsrcX, nullptr);
3211 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003212}
3213
solenberg2100c0b2017-03-01 11:29:29 -08003214TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003215 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003216 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3217 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003218 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3219 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003220
3221 // Should be able to set a default sink even when no stream exists.
3222 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3223
solenberg2100c0b2017-03-01 11:29:29 -08003224 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3225 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003226 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003227 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003228
3229 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003230 channel_->SetRawAudioSink(kSsrc0, nullptr);
3231 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003232
3233 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003234 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3235 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003236
3237 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003239 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003240 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3241
3242 // Spawn another unsignaled stream - it should be assigned the default sink
3243 // and the previous unsignaled stream should lose it.
3244 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3245 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3246 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3247 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003248 if (kMaxUnsignaledRecvStreams > 1) {
3249 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3250 }
solenberg2100c0b2017-03-01 11:29:29 -08003251 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3252
3253 // Reset the default sink - the second unsignaled stream should lose it.
3254 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003255 if (kMaxUnsignaledRecvStreams > 1) {
3256 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3257 }
solenberg2100c0b2017-03-01 11:29:29 -08003258 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3259
3260 // Try setting the default sink while two streams exists.
3261 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003262 if (kMaxUnsignaledRecvStreams > 1) {
3263 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3264 }
solenberg2100c0b2017-03-01 11:29:29 -08003265 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3266
3267 // Try setting the sink for the first unsignaled stream using its known SSRC.
3268 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003269 if (kMaxUnsignaledRecvStreams > 1) {
3270 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3271 }
solenberg2100c0b2017-03-01 11:29:29 -08003272 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003273 if (kMaxUnsignaledRecvStreams > 1) {
3274 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3275 }
deadbeef884f5852016-01-15 09:20:04 -08003276}
3277
skvlad7a43d252016-03-22 15:32:27 -07003278// Test that, just like the video channel, the voice channel communicates the
3279// network state to the call.
3280TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003281 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003282
3283 EXPECT_EQ(webrtc::kNetworkUp,
3284 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3285 EXPECT_EQ(webrtc::kNetworkUp,
3286 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3287
3288 channel_->OnReadyToSend(false);
3289 EXPECT_EQ(webrtc::kNetworkDown,
3290 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3291 EXPECT_EQ(webrtc::kNetworkUp,
3292 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3293
3294 channel_->OnReadyToSend(true);
3295 EXPECT_EQ(webrtc::kNetworkUp,
3296 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3297 EXPECT_EQ(webrtc::kNetworkUp,
3298 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3299}
3300
aleloi18e0b672016-10-04 02:45:47 -07003301// Test that playout is still started after changing parameters
3302TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3303 SetupRecvStream();
3304 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003305 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003306
3307 // Changing RTP header extensions will recreate the AudioReceiveStream.
3308 cricket::AudioRecvParameters parameters;
3309 parameters.extensions.push_back(
3310 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3311 channel_->SetRecvParameters(parameters);
3312
solenberg2100c0b2017-03-01 11:29:29 -08003313 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003314}
3315
stefan658910c2015-09-03 05:48:32 -07003316// Tests that the library initializes and shuts down properly.
3317TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003318 // If the VoiceEngine wants to gather available codecs early, that's fine but
3319 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003320 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003321 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3322 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003323 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003324 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003325 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003326 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003327 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003328 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003329 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003330 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3331 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003332 EXPECT_TRUE(channel != nullptr);
3333 delete channel;
solenbergff976312016-03-30 23:28:51 -07003334}
stefan658910c2015-09-03 05:48:32 -07003335
solenbergff976312016-03-30 23:28:51 -07003336// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003337TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3338 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003339 EXPECT_CALL(adm, AddRef()).Times(3);
3340 EXPECT_CALL(adm, Release())
3341 .Times(3)
3342 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003343 {
peaha9cc40b2017-06-29 08:32:09 -07003344 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3345 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003346 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003347 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003348 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003349 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003350 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003351 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003352 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003353 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3354 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3355 EXPECT_TRUE(channel != nullptr);
3356 delete channel;
3357 }
stefan658910c2015-09-03 05:48:32 -07003358}
3359
ossu20a4b3f2017-04-27 02:08:52 -07003360// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3361TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003362 // TODO(ossu): Why are the payload types of codecs with non-static payload
3363 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003364 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003365 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3366 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003367 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003368 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003369 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003370 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003371 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003372 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3373 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3374 (clockrate == 0 || codec.clockrate == clockrate);
3375 };
3376 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003382 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003384 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003385 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003386 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003387 EXPECT_EQ(126, codec.id);
3388 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3389 // Remove these checks once both send and receive side assigns payload types
3390 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003391 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003392 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003393 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003394 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003395 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003396 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003397 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(111, codec.id);
3399 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3400 EXPECT_EQ("10", codec.params.find("minptime")->second);
3401 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3402 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003403 }
3404 }
stefan658910c2015-09-03 05:48:32 -07003405}
3406
3407// Tests that VoE supports at least 32 channels
3408TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003409 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003410 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3411 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003412 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003413 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003414 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003415 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003416 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003417 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003418 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003419
3420 cricket::VoiceMediaChannel* channels[32];
3421 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003422 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003423 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3424 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003425 if (!channel)
3426 break;
stefan658910c2015-09-03 05:48:32 -07003427 channels[num_channels++] = channel;
3428 }
3429
tfarina5237aaf2015-11-10 23:44:30 -08003430 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003431 EXPECT_EQ(expected, num_channels);
3432
3433 while (num_channels > 0) {
3434 delete channels[--num_channels];
3435 }
stefan658910c2015-09-03 05:48:32 -07003436}
3437
3438// Test that we set our preferred codecs properly.
3439TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003440 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3441 // - Check that our builtin codecs are usable by Channel.
3442 // - The codecs provided by the engine is usable by Channel.
3443 // It does not check that the codecs in the RecvParameters are actually
3444 // what we sent in - though it's probably reasonable to expect so, if
3445 // SetRecvParameters returns true.
3446 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003447 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003448 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3449 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003450 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003451 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003452 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003453 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003454 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003455 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003456 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003457 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3458 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003459 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003460 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003461 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003462}
ossu9def8002017-02-09 05:14:32 -08003463
3464TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3465 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003466 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3467 {48000, 2, 16000, 10000, 20000}};
3468 spec1.info.allow_comfort_noise = false;
3469 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003470 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003471 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3472 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003473 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003474 specs.push_back(webrtc::AudioCodecSpec{
3475 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3476 {16000, 1, 13300}});
3477 specs.push_back(
3478 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3479 specs.push_back(
3480 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003481
ossueb1fde42017-05-02 06:46:30 -07003482 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3483 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3484 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003485 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003486 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003487 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003488 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003489
peaha9cc40b2017-06-29 08:32:09 -07003490 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3491 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003492 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003493 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003494 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003495 auto codecs = engine.recv_codecs();
3496 EXPECT_EQ(11, codecs.size());
3497
3498 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3499 // check the actual values safely, to provide better test results.
3500 auto get_codec =
3501 [&codecs](size_t index) -> const cricket::AudioCodec& {
3502 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3503 if (codecs.size() > index)
3504 return codecs[index];
3505 return missing_codec;
3506 };
3507
3508 // Ensure the general codecs are generated first and in order.
3509 for (size_t i = 0; i != specs.size(); ++i) {
3510 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3511 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3512 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3513 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3514 }
3515
3516 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003517 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003518 auto find_codec =
3519 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3520 for (size_t i = 0; i != codecs.size(); ++i) {
3521 const cricket::AudioCodec& codec = codecs[i];
3522 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3523 codec.clockrate == format.clockrate_hz &&
3524 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003525 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003526 }
3527 }
3528 return -1;
3529 };
3530
3531 // Ensure all supplementary codecs are generated last. Their internal ordering
3532 // is not important.
3533 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3534 const int num_specs = static_cast<int>(specs.size());
3535 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3536 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3537 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3538 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3539 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3540 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3541 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3542}