blob: 0a165f57488090228fae85cc2e80e6226ff8b92b [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));
211 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
212 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
213 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700214 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800215 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700216 // factories. Those tests should probably be moved elsewhere.
217 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
218 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
219 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700220 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700221 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700222 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200223 send_parameters_.codecs.push_back(kPcmuCodec);
224 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100225
solenberg76377c52017-02-21 00:54:31 -0800226 // Default Options.
227 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 }
solenberg8189b022016-06-14 12:13:00 -0700229
solenbergff976312016-03-30 23:28:51 -0700230 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700231 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700232 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
233 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200234 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000235 }
solenberg8189b022016-06-14 12:13:00 -0700236
solenbergff976312016-03-30 23:28:51 -0700237 bool SetupRecvStream() {
238 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700239 return false;
240 }
solenberg2100c0b2017-03-01 11:29:29 -0800241 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700242 }
solenberg8189b022016-06-14 12:13:00 -0700243
solenbergff976312016-03-30 23:28:51 -0700244 bool SetupSendStream() {
245 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000246 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 }
solenberg2100c0b2017-03-01 11:29:29 -0800248 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800249 return false;
250 }
peaha9cc40b2017-06-29 08:32:09 -0700251 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800252 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 }
solenberg8189b022016-06-14 12:13:00 -0700254
255 bool AddRecvStream(uint32_t ssrc) {
256 EXPECT_TRUE(channel_);
257 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
258 }
259
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000260 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700261 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700262 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800263 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
264 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700265 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800266 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000267 }
solenberg8189b022016-06-14 12:13:00 -0700268
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700270 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000271 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 }
solenberg8189b022016-06-14 12:13:00 -0700273
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200274 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 }
277
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100278 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
279 const auto* send_stream = call_.GetAudioSendStream(ssrc);
280 EXPECT_TRUE(send_stream);
281 return *send_stream;
282 }
283
deadbeef884f5852016-01-15 09:20:04 -0800284 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
285 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
286 EXPECT_TRUE(recv_stream);
287 return *recv_stream;
288 }
289
solenberg3a941542015-11-16 07:34:50 -0800290 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800291 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800292 }
293
solenberg7add0582015-11-20 09:59:34 -0800294 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800295 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800296 }
297
solenberg059fb442016-10-26 05:12:24 -0700298 void SetSend(bool enable) {
299 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700300 if (enable) {
301 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
302 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
303 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700304 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700305 }
solenberg059fb442016-10-26 05:12:24 -0700306 channel_->SetSend(enable);
307 }
308
309 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700310 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700311 ASSERT_TRUE(channel_);
312 EXPECT_TRUE(channel_->SetSendParameters(params));
313 }
314
minyue6b825df2016-10-31 04:08:32 -0700315 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
316 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700317 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700318 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700319 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700320 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700321 }
322 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700323 }
324
solenbergffbbcac2016-11-17 05:25:37 -0800325 void TestInsertDtmf(uint32_t ssrc, bool caller,
326 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700327 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000328 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700329 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330 // send stream.
331 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800332 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000333 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000334
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700336 SetSendParameters(send_parameters_);
337 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800340 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700341 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000343
344 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700345 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800346 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000347 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800348 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000349 }
350
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800352 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100354 // Test send.
355 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800356 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100357 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800358 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800359 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800360 EXPECT_EQ(codec.id, telephone_event.payload_type);
361 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100362 EXPECT_EQ(2, telephone_event.event_code);
363 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 }
365
366 // Test that send bandwidth is set correctly.
367 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000368 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
369 // |expected_result| is the expected result from SetMaxSendBandwidth().
370 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700371 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
372 int max_bitrate,
373 bool expected_result,
374 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200375 cricket::AudioSendParameters parameters;
376 parameters.codecs.push_back(codec);
377 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700378 if (expected_result) {
379 SetSendParameters(parameters);
380 } else {
381 EXPECT_FALSE(channel_->SetSendParameters(parameters));
382 }
solenberg2100c0b2017-03-01 11:29:29 -0800383 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384 }
385
skvlade0d46372016-04-07 22:59:22 -0700386 // Sets the per-stream maximum bitrate limit for the specified SSRC.
387 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700388 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700389 EXPECT_EQ(1UL, parameters.encodings.size());
390
Oskar Sundbom78807582017-11-16 11:09:55 +0100391 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700392 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
solenberg059fb442016-10-26 05:12:24 -0700395 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700396 cricket::AudioSendParameters send_parameters;
397 send_parameters.codecs.push_back(codec);
398 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700399 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700400 }
401
ossu20a4b3f2017-04-27 02:08:52 -0700402 void CheckSendCodecBitrate(int32_t ssrc,
403 const char expected_name[],
404 int expected_bitrate) {
405 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
406 EXPECT_EQ(expected_name, spec->format.name);
407 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700408 }
409
ossu20a4b3f2017-04-27 02:08:52 -0700410 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
411 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700412 }
413
minyue6b825df2016-10-31 04:08:32 -0700414 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
415 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
416 }
417
skvlade0d46372016-04-07 22:59:22 -0700418 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
419 int global_max,
420 int stream_max,
421 bool expected_result,
422 int expected_codec_bitrate) {
423 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800424 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700425
426 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700427 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800428 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700429
430 // Verify that reading back the parameters gives results
431 // consistent with the Set() result.
432 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800433 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700434 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
435 EXPECT_EQ(expected_result ? stream_max : -1,
436 resulting_parameters.encodings[0].max_bitrate_bps);
437
438 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800439 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700440 }
441
stefan13f1a0a2016-11-30 07:22:58 -0800442 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
443 int expected_min_bitrate_bps,
444 const char* start_bitrate_kbps,
445 int expected_start_bitrate_bps,
446 const char* max_bitrate_kbps,
447 int expected_max_bitrate_bps) {
448 EXPECT_TRUE(SetupSendStream());
449 auto& codecs = send_parameters_.codecs;
450 codecs.clear();
451 codecs.push_back(kOpusCodec);
452 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
453 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
454 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
455 SetSendParameters(send_parameters_);
456
457 EXPECT_EQ(expected_min_bitrate_bps,
458 call_.GetConfig().bitrate_config.min_bitrate_bps);
459 EXPECT_EQ(expected_start_bitrate_bps,
460 call_.GetConfig().bitrate_config.start_bitrate_bps);
461 EXPECT_EQ(expected_max_bitrate_bps,
462 call_.GetConfig().bitrate_config.max_bitrate_bps);
463 }
464
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000465 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700466 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000467
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000468 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800469 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
471 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700472 send_parameters_.extensions.push_back(
473 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700474 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800475 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000476
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000477 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200478 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700479 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800480 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000481
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000482 // Ensure extension is set properly.
483 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700484 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700485 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800486 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
487 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
488 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000489
solenberg7add0582015-11-20 09:59:34 -0800490 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000491 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800492 cricket::StreamParams::CreateLegacy(kSsrcY)));
493 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
494 call_.GetAudioSendStream(kSsrcY));
495 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
496 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
497 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000498
499 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200500 send_parameters_.codecs.push_back(kPcmuCodec);
501 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700502 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
504 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505 }
506
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000507 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700508 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000509
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000510 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800511 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
513 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700514 recv_parameters_.extensions.push_back(
515 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800516 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800517 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000518
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000519 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800520 recv_parameters_.extensions.clear();
521 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800522 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000523
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000524 // Ensure extension is set properly.
525 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700526 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800527 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800528 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
529 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
530 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000531
solenberg7add0582015-11-20 09:59:34 -0800532 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800533 EXPECT_TRUE(AddRecvStream(kSsrcY));
534 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
535 call_.GetAudioReceiveStream(kSsrcY));
536 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
537 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
538 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000539
540 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800541 recv_parameters_.extensions.clear();
542 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800543 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
544 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000545 }
546
solenberg85a04962015-10-27 03:35:21 -0700547 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
548 webrtc::AudioSendStream::Stats stats;
549 stats.local_ssrc = 12;
550 stats.bytes_sent = 345;
551 stats.packets_sent = 678;
552 stats.packets_lost = 9012;
553 stats.fraction_lost = 34.56f;
554 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100555 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700556 stats.ext_seqnum = 789;
557 stats.jitter_ms = 12;
558 stats.rtt_ms = 345;
559 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100560 stats.apm_statistics.delay_median_ms = 234;
561 stats.apm_statistics.delay_standard_deviation_ms = 567;
562 stats.apm_statistics.echo_return_loss = 890;
563 stats.apm_statistics.echo_return_loss_enhancement = 1234;
564 stats.apm_statistics.residual_echo_likelihood = 0.432f;
565 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100566 stats.ana_statistics.bitrate_action_counter = 321;
567 stats.ana_statistics.channel_action_counter = 432;
568 stats.ana_statistics.dtx_action_counter = 543;
569 stats.ana_statistics.fec_action_counter = 654;
570 stats.ana_statistics.frame_length_increase_counter = 765;
571 stats.ana_statistics.frame_length_decrease_counter = 876;
572 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700573 stats.typing_noise_detected = true;
574 return stats;
575 }
576 void SetAudioSendStreamStats() {
577 for (auto* s : call_.GetAudioSendStreams()) {
578 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200579 }
solenberg85a04962015-10-27 03:35:21 -0700580 }
solenberg566ef242015-11-06 15:34:49 -0800581 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
582 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700583 const auto stats = GetAudioSendStreamStats();
584 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
585 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
586 EXPECT_EQ(info.packets_sent, stats.packets_sent);
587 EXPECT_EQ(info.packets_lost, stats.packets_lost);
588 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
589 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800590 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700591 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
592 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
593 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
594 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100595 EXPECT_EQ(info.apm_statistics.delay_median_ms,
596 stats.apm_statistics.delay_median_ms);
597 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
598 stats.apm_statistics.delay_standard_deviation_ms);
599 EXPECT_EQ(info.apm_statistics.echo_return_loss,
600 stats.apm_statistics.echo_return_loss);
601 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
602 stats.apm_statistics.echo_return_loss_enhancement);
603 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
604 stats.apm_statistics.residual_echo_likelihood);
605 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
606 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700607 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
608 stats.ana_statistics.bitrate_action_counter);
609 EXPECT_EQ(info.ana_statistics.channel_action_counter,
610 stats.ana_statistics.channel_action_counter);
611 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
612 stats.ana_statistics.dtx_action_counter);
613 EXPECT_EQ(info.ana_statistics.fec_action_counter,
614 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700615 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
616 stats.ana_statistics.frame_length_increase_counter);
617 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
618 stats.ana_statistics.frame_length_decrease_counter);
619 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
620 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800621 EXPECT_EQ(info.typing_noise_detected,
622 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700623 }
624
625 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
626 webrtc::AudioReceiveStream::Stats stats;
627 stats.remote_ssrc = 123;
628 stats.bytes_rcvd = 456;
629 stats.packets_rcvd = 768;
630 stats.packets_lost = 101;
631 stats.fraction_lost = 23.45f;
632 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100633 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700634 stats.ext_seqnum = 678;
635 stats.jitter_ms = 901;
636 stats.jitter_buffer_ms = 234;
637 stats.jitter_buffer_preferred_ms = 567;
638 stats.delay_estimate_ms = 890;
639 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700640 stats.total_samples_received = 5678901;
641 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200642 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200643 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700644 stats.expand_rate = 5.67f;
645 stats.speech_expand_rate = 8.90f;
646 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200647 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700648 stats.accelerate_rate = 4.56f;
649 stats.preemptive_expand_rate = 7.89f;
650 stats.decoding_calls_to_silence_generator = 12;
651 stats.decoding_calls_to_neteq = 345;
652 stats.decoding_normal = 67890;
653 stats.decoding_plc = 1234;
654 stats.decoding_cng = 5678;
655 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700656 stats.decoding_muted_output = 3456;
657 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200658 return stats;
659 }
660 void SetAudioReceiveStreamStats() {
661 for (auto* s : call_.GetAudioReceiveStreams()) {
662 s->SetStats(GetAudioReceiveStreamStats());
663 }
664 }
665 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700666 const auto stats = GetAudioReceiveStreamStats();
667 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
668 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
669 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
670 EXPECT_EQ(info.packets_lost, stats.packets_lost);
671 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
672 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800673 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700674 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
675 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
676 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200677 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700678 stats.jitter_buffer_preferred_ms);
679 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
680 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700681 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
682 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200683 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200684 EXPECT_EQ(info.jitter_buffer_delay_seconds,
685 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700686 EXPECT_EQ(info.expand_rate, stats.expand_rate);
687 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
688 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200689 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700690 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
691 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200692 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700693 stats.decoding_calls_to_silence_generator);
694 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
695 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
696 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
697 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
698 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700699 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700700 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200701 }
hbos1acfbd22016-11-17 23:43:29 -0800702 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
703 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
704 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
705 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
706 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
707 codec.ToCodecParameters());
708 }
709 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
710 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
711 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
712 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
713 codec.ToCodecParameters());
714 }
715 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200716
peah8271d042016-11-22 07:24:52 -0800717 bool IsHighPassFilterEnabled() {
718 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
719 }
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700722 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700723 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800724 webrtc::test::MockGainControl& apm_gc_;
725 webrtc::test::MockEchoCancellation& apm_ec_;
726 webrtc::test::MockNoiseSuppression& apm_ns_;
727 webrtc::test::MockVoiceDetection& apm_vd_;
728 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700729 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200730 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700732 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700733 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200734 cricket::AudioSendParameters send_parameters_;
735 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800736 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700737 webrtc::AudioProcessing::Config apm_config_;
738
stefanba4c0e42016-02-04 04:12:24 -0800739 private:
740 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741};
742
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743// Tests that we can create and destroy a channel.
744TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700745 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746}
747
solenberg31fec402016-05-06 02:13:12 -0700748// Test that we can add a send stream and that it has the correct defaults.
749TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
750 EXPECT_TRUE(SetupChannel());
751 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800752 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
753 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
754 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700755 EXPECT_EQ("", config.rtp.c_name);
756 EXPECT_EQ(0u, config.rtp.extensions.size());
757 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
758 config.send_transport);
759}
760
761// Test that we can add a receive stream and that it has the correct defaults.
762TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
763 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800764 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700765 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800766 GetRecvStreamConfig(kSsrcX);
767 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700768 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
769 EXPECT_FALSE(config.rtp.transport_cc);
770 EXPECT_EQ(0u, config.rtp.extensions.size());
771 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
772 config.rtcp_send_transport);
773 EXPECT_EQ("", config.sync_group);
774}
775
stefanba4c0e42016-02-04 04:12:24 -0800776TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700777 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800778 bool opus_found = false;
779 for (cricket::AudioCodec codec : codecs) {
780 if (codec.name == "opus") {
781 EXPECT_TRUE(HasTransportCc(codec));
782 opus_found = true;
783 }
784 }
785 EXPECT_TRUE(opus_found);
786}
787
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788// Test that we set our inbound codecs properly, including changing PT.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
793 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800794 parameters.codecs.push_back(kTelephoneEventCodec1);
795 parameters.codecs.push_back(kTelephoneEventCodec2);
796 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 parameters.codecs[2].id = 126;
798 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800799 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700800 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
801 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
802 {{0, {"PCMU", 8000, 1}},
803 {106, {"ISAC", 16000, 1}},
804 {126, {"telephone-event", 8000, 1}},
805 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806}
807
808// Test that we fail to set an unknown inbound codec.
809TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700810 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200811 cricket::AudioRecvParameters parameters;
812 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700813 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815}
816
817// Test that we fail if we have duplicate types in the inbound list.
818TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700819 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200820 cricket::AudioRecvParameters parameters;
821 parameters.codecs.push_back(kIsacCodec);
822 parameters.codecs.push_back(kCn16000Codec);
823 parameters.codecs[1].id = kIsacCodec.id;
824 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825}
826
827// Test that we can decode OPUS without stereo parameters.
828TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700829 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 cricket::AudioRecvParameters parameters;
831 parameters.codecs.push_back(kIsacCodec);
832 parameters.codecs.push_back(kPcmuCodec);
833 parameters.codecs.push_back(kOpusCodec);
834 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800835 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700836 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
837 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
838 {{0, {"PCMU", 8000, 1}},
839 {103, {"ISAC", 16000, 1}},
840 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can decode OPUS with stereo = 0.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kPcmuCodec);
849 parameters.codecs.push_back(kOpusCodec);
850 parameters.codecs[2].params["stereo"] = "0";
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700853 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
854 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
855 {{0, {"PCMU", 8000, 1}},
856 {103, {"ISAC", 16000, 1}},
857 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that we can decode OPUS with stereo = 1.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
866 parameters.codecs.push_back(kOpusCodec);
867 parameters.codecs[2].params["stereo"] = "1";
868 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800869 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700870 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
871 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
872 {{0, {"PCMU", 8000, 1}},
873 {103, {"ISAC", 16000, 1}},
874 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875}
876
877// Test that changes to recv codecs are applied to all streams.
878TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700879 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200880 cricket::AudioRecvParameters parameters;
881 parameters.codecs.push_back(kIsacCodec);
882 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800883 parameters.codecs.push_back(kTelephoneEventCodec1);
884 parameters.codecs.push_back(kTelephoneEventCodec2);
885 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200886 parameters.codecs[2].id = 126;
887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700888 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
889 EXPECT_TRUE(AddRecvStream(ssrc));
890 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
891 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
892 {{0, {"PCMU", 8000, 1}},
893 {106, {"ISAC", 16000, 1}},
894 {126, {"telephone-event", 8000, 1}},
895 {107, {"telephone-event", 32000, 1}}})));
896 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897}
898
899TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700900 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200901 cricket::AudioRecvParameters parameters;
902 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800903 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905
solenberg2100c0b2017-03-01 11:29:29 -0800906 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800907 ASSERT_EQ(1, dm.count(106));
908 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can apply the same set of codecs again while playing.
912TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kCn16000Codec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700918 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200919 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
deadbeefcb383672017-04-26 16:28:42 -0700921 // Remapping a payload type to a different codec should fail.
922 parameters.codecs[0] = kOpusCodec;
923 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200924 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800925 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926}
927
928// Test that we can add a codec while playing.
929TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700930 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 cricket::AudioRecvParameters parameters;
932 parameters.codecs.push_back(kIsacCodec);
933 parameters.codecs.push_back(kCn16000Codec);
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700935 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200937 parameters.codecs.push_back(kOpusCodec);
938 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800939 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
deadbeefcb383672017-04-26 16:28:42 -0700942// Test that we accept adding the same codec with a different payload type.
943// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
944TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
945 EXPECT_TRUE(SetupRecvStream());
946 cricket::AudioRecvParameters parameters;
947 parameters.codecs.push_back(kIsacCodec);
948 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
949
950 ++parameters.codecs[0].id;
951 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
952}
953
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000957 // Test that when autobw is enabled, bitrate is kept as the default
958 // value. autobw is enabled for the following tests because the target
959 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960
961 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700962 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
964 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700965 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966
ossu20a4b3f2017-04-27 02:08:52 -0700967 // opus, default bitrate == 32000 in mono.
968 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700972 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700975 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
976 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700977 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000979 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700980 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
981 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
982 // Rates above the max (510000) should be capped.
983 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984}
985
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000986TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700987 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000988
989 // Test that we can only set a maximum bitrate for a fixed-rate codec
990 // if it's bigger than the fixed rate.
991
992 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700993 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
995 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
996 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001000}
1001
1002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001004 const int kDesiredBitrate = 128000;
1005 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001006 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001007 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001008 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001009
1010 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001011 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001012
solenberg2100c0b2017-03-01 11:29:29 -08001013 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001014}
1015
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016// Test that bitrate cannot be set for CBR codecs.
1017// Bitrate is ignored if it is higher than the fixed bitrate.
1018// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001019TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001020 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021
1022 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001023 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001024 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001025
1026 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001027 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001028 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029
1030 send_parameters_.max_bandwidth_bps = 128;
1031 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001032 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001033}
1034
skvlade0d46372016-04-07 22:59:22 -07001035// Test that the per-stream bitrate limit and the global
1036// bitrate limit both apply.
1037TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1038 EXPECT_TRUE(SetupSendStream());
1039
ossu20a4b3f2017-04-27 02:08:52 -07001040 // opus, default bitrate == 32000.
1041 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001042 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1043 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1044 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1045
1046 // CBR codecs allow both maximums to exceed the bitrate.
1047 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1049 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1050 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1051
1052 // CBR codecs don't allow per stream maximums to be too low.
1053 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1054 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1055}
1056
1057// Test that an attempt to set RtpParameters for a stream that does not exist
1058// fails.
1059TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1060 EXPECT_TRUE(SetupChannel());
1061 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001062 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001063 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1064
1065 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001067}
1068
1069TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001070 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001071 // This test verifies that setting RtpParameters succeeds only if
1072 // the structure contains exactly one encoding.
1073 // TODO(skvlad): Update this test when we start supporting setting parameters
1074 // for each encoding individually.
1075
1076 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001077 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001078 // Two or more encodings should result in failure.
1079 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001080 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001081 // Zero encodings should also fail.
1082 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001083 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001084}
1085
1086// Changing the SSRC through RtpParameters is not allowed.
1087TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1088 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001089 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001090 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001091 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001092}
1093
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001095// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001096TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1097 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001098 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001099 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001100 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001101 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001102 ASSERT_EQ(1u, parameters.encodings.size());
1103 ASSERT_TRUE(parameters.encodings[0].active);
1104 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001105 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1106 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001107
1108 // Now change it back to active and verify we resume sending.
1109 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001110 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1111 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001112}
1113
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001114// Test that SetRtpSendParameters configures the correct encoding channel for
1115// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001116TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1117 SetupForMultiSendStream();
1118 // Create send streams.
1119 for (uint32_t ssrc : kSsrcs4) {
1120 EXPECT_TRUE(
1121 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1122 }
1123 // Configure one stream to be limited by the stream config, another to be
1124 // limited by the global max, and the third one with no per-stream limit
1125 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001126 SetGlobalMaxBitrate(kOpusCodec, 32000);
1127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1128 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001129 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1130
ossu20a4b3f2017-04-27 02:08:52 -07001131 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1132 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1133 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001134
1135 // Remove the global cap; the streams should switch to their respective
1136 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001137 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001138 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1139 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1140 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001141}
1142
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001143// Test that GetRtpSendParameters returns the currently configured codecs.
1144TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001145 EXPECT_TRUE(SetupSendStream());
1146 cricket::AudioSendParameters parameters;
1147 parameters.codecs.push_back(kIsacCodec);
1148 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001149 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150
solenberg2100c0b2017-03-01 11:29:29 -08001151 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001153 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1154 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155}
1156
deadbeefcb443432016-12-12 11:12:36 -08001157// Test that GetRtpSendParameters returns an SSRC.
1158TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1159 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001160 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001161 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001162 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001163}
1164
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001166TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001167 EXPECT_TRUE(SetupSendStream());
1168 cricket::AudioSendParameters parameters;
1169 parameters.codecs.push_back(kIsacCodec);
1170 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001171 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001172
solenberg2100c0b2017-03-01 11:29:29 -08001173 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001174
1175 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001176 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001177
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001178 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001179 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1180 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001181}
1182
minyuececec102017-03-27 13:04:25 -07001183// Test that max_bitrate_bps in send stream config gets updated correctly when
1184// SetRtpSendParameters is called.
1185TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1186 webrtc::test::ScopedFieldTrials override_field_trials(
1187 "WebRTC-Audio-SendSideBwe/Enabled/");
1188 EXPECT_TRUE(SetupSendStream());
1189 cricket::AudioSendParameters send_parameters;
1190 send_parameters.codecs.push_back(kOpusCodec);
1191 SetSendParameters(send_parameters);
1192
1193 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1194 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1195 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1196
1197 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001198 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001199 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1200
1201 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1202 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1203}
1204
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001205// Test that GetRtpReceiveParameters returns the currently configured codecs.
1206TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1207 EXPECT_TRUE(SetupRecvStream());
1208 cricket::AudioRecvParameters parameters;
1209 parameters.codecs.push_back(kIsacCodec);
1210 parameters.codecs.push_back(kPcmuCodec);
1211 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1212
1213 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001214 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001215 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1216 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1217 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1218}
1219
deadbeefcb443432016-12-12 11:12:36 -08001220// Test that GetRtpReceiveParameters returns an SSRC.
1221TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1222 EXPECT_TRUE(SetupRecvStream());
1223 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001224 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001225 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001226 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001227}
1228
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001229// Test that if we set/get parameters multiple times, we get the same results.
1230TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1231 EXPECT_TRUE(SetupRecvStream());
1232 cricket::AudioRecvParameters parameters;
1233 parameters.codecs.push_back(kIsacCodec);
1234 parameters.codecs.push_back(kPcmuCodec);
1235 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1236
1237 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001238 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001239
1240 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001241 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001242
1243 // ... And this shouldn't change the params returned by
1244 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001245 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1246 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001247}
1248
deadbeef3bc15102017-04-20 19:25:07 -07001249// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1250// aren't signaled. It should return an empty "RtpEncodingParameters" when
1251// configured to receive an unsignaled stream and no packets have been received
1252// yet, and start returning the SSRC once a packet has been received.
1253TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1254 ASSERT_TRUE(SetupChannel());
1255 // Call necessary methods to configure receiving a default stream as
1256 // soon as it arrives.
1257 cricket::AudioRecvParameters parameters;
1258 parameters.codecs.push_back(kIsacCodec);
1259 parameters.codecs.push_back(kPcmuCodec);
1260 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1261
1262 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1263 // stream. Should return nothing.
1264 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1265
1266 // Set a sink for an unsignaled stream.
1267 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1268 // Value of "0" means "unsignaled stream".
1269 channel_->SetRawAudioSink(0, std::move(fake_sink));
1270
1271 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1272 // in this method means "unsignaled stream".
1273 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1274 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1275 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1276
1277 // Receive PCMU packet (SSRC=1).
1278 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1279
1280 // The |ssrc| member should still be unset.
1281 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1282 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1283 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1284}
1285
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001286// Test that we apply codecs properly.
1287TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001288 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 cricket::AudioSendParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001292 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001293 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001294 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001295 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001296 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1297 EXPECT_EQ(96, send_codec_spec.payload_type);
1298 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1299 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1300 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001301 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001302 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303}
1304
ossu20a4b3f2017-04-27 02:08:52 -07001305// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1306// AudioSendStream.
1307TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001308 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001309 cricket::AudioSendParameters parameters;
1310 parameters.codecs.push_back(kIsacCodec);
1311 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001312 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001313 parameters.codecs[0].id = 96;
1314 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001315 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001316 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001317 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001318 // Calling SetSendCodec again with same codec which is already set.
1319 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001320 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001321 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001322}
1323
ossu20a4b3f2017-04-27 02:08:52 -07001324// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1325// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001326
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001327// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001328TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001329 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001330 cricket::AudioSendParameters parameters;
1331 parameters.codecs.push_back(kOpusCodec);
1332 parameters.codecs[0].bitrate = 0;
1333 parameters.codecs[0].clockrate = 50000;
1334 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001337// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].channels = 0;
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001347// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
1353 parameters.codecs[0].channels = 0;
1354 parameters.codecs[0].params["stereo"] = "1";
1355 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
1358// Test that if channel is 1 for opus and there's no stereo, we fail.
1359TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001360 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 cricket::AudioSendParameters parameters;
1362 parameters.codecs.push_back(kOpusCodec);
1363 parameters.codecs[0].bitrate = 0;
1364 parameters.codecs[0].channels = 1;
1365 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
1368// Test that if channel is 1 for opus and stereo=0, we fail.
1369TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001370 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 cricket::AudioSendParameters parameters;
1372 parameters.codecs.push_back(kOpusCodec);
1373 parameters.codecs[0].bitrate = 0;
1374 parameters.codecs[0].channels = 1;
1375 parameters.codecs[0].params["stereo"] = "0";
1376 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377}
1378
1379// Test that if channel is 1 for opus and stereo=1, we fail.
1380TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001381 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 0;
1385 parameters.codecs[0].channels = 1;
1386 parameters.codecs[0].params["stereo"] = "1";
1387 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388}
1389
ossu20a4b3f2017-04-27 02:08:52 -07001390// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001392 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 cricket::AudioSendParameters parameters;
1394 parameters.codecs.push_back(kOpusCodec);
1395 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001396 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001397 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
ossu20a4b3f2017-04-27 02:08:52 -07001400// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].bitrate = 0;
1406 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001407 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001408 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409}
1410
ossu20a4b3f2017-04-27 02:08:52 -07001411// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001412TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001413 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 cricket::AudioSendParameters parameters;
1415 parameters.codecs.push_back(kOpusCodec);
1416 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001417 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001419 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001420 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001421
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001422 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001425}
1426
ossu20a4b3f2017-04-27 02:08:52 -07001427// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].bitrate = 0;
1433 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436}
1437
ossu20a4b3f2017-04-27 02:08:52 -07001438// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001444 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001448
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001451 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001452}
1453
ossu20a4b3f2017-04-27 02:08:52 -07001454// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001461 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1462 EXPECT_EQ(111, spec.payload_type);
1463 EXPECT_EQ(96000, spec.target_bitrate_bps);
1464 EXPECT_EQ("opus", spec.format.name);
1465 EXPECT_EQ(2, spec.format.num_channels);
1466 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467}
1468
ossu20a4b3f2017-04-27 02:08:52 -07001469// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 30000;
1475 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001477 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001478}
1479
ossu20a4b3f2017-04-27 02:08:52 -07001480// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001482 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001483 cricket::AudioSendParameters parameters;
1484 parameters.codecs.push_back(kOpusCodec);
1485 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001487 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
ossu20a4b3f2017-04-27 02:08:52 -07001490// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001492 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001493 cricket::AudioSendParameters parameters;
1494 parameters.codecs.push_back(kOpusCodec);
1495 parameters.codecs[0].bitrate = 30000;
1496 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001497 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001498 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001499}
1500
stefan13f1a0a2016-11-30 07:22:58 -08001501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1502 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1503 200000);
1504}
1505
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1507 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1508}
1509
1510TEST_F(WebRtcVoiceEngineTestFake,
1511 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1512 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1513}
1514
1515TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1516 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1517}
1518
1519TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001520 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001521 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1522 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001523 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001524 SetSendParameters(send_parameters_);
1525 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1526 << "Setting max bitrate should keep previous min bitrate.";
1527 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1528 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001529 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001530}
1531
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001532// Test that we can enable NACK with opus as caller.
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001534 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].AddFeedbackParam(
1538 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1539 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543}
1544
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001545// Test that we can enable NACK with opus as callee.
1546TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001547 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001548 cricket::AudioSendParameters parameters;
1549 parameters.codecs.push_back(kOpusCodec);
1550 parameters.codecs[0].AddFeedbackParam(
1551 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1552 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001553 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001554 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001555 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001557
1558 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001559 cricket::StreamParams::CreateLegacy(kSsrcX)));
1560 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001561}
1562
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563// Test that we can enable NACK on receive streams.
1564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001565 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001566 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].AddFeedbackParam(
1570 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1571 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1573 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1576 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
1579// Test that we can disable NACK.
1580TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001581 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001582 cricket::AudioSendParameters parameters;
1583 parameters.codecs.push_back(kOpusCodec);
1584 parameters.codecs[0].AddFeedbackParam(
1585 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1586 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001587 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001590 parameters.codecs.clear();
1591 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001593 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001594}
1595
1596// Test that we can disable NACK on receive streams.
1597TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001598 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 cricket::AudioSendParameters parameters;
1601 parameters.codecs.push_back(kOpusCodec);
1602 parameters.codecs[0].AddFeedbackParam(
1603 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1604 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001606 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1607 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 parameters.codecs.clear();
1610 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001611 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1613 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
1616// Test that NACK is enabled on a new receive stream.
1617TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kIsacCodec);
1621 parameters.codecs.push_back(kCn16000Codec);
1622 parameters.codecs[0].AddFeedbackParam(
1623 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1624 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001626 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001627
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_TRUE(AddRecvStream(kSsrcY));
1629 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1630 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1631 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632}
1633
stefanba4c0e42016-02-04 04:12:24 -08001634TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001635 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001636 cricket::AudioSendParameters send_parameters;
1637 send_parameters.codecs.push_back(kOpusCodec);
1638 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001639 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001640
1641 cricket::AudioRecvParameters recv_parameters;
1642 recv_parameters.codecs.push_back(kIsacCodec);
1643 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001644 EXPECT_TRUE(AddRecvStream(kSsrcX));
1645 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001646 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001647 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001648
ossudedfd282016-06-14 07:12:39 -07001649 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001650 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001651 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001652 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001653 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001654}
1655
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001656// Test that we can switch back and forth between Opus and ISAC with CN.
1657TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001658 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001659
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001660 cricket::AudioSendParameters opus_parameters;
1661 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001662 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001663 {
ossu20a4b3f2017-04-27 02:08:52 -07001664 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1665 EXPECT_EQ(111, spec.payload_type);
1666 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001667 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001669 cricket::AudioSendParameters isac_parameters;
1670 isac_parameters.codecs.push_back(kIsacCodec);
1671 isac_parameters.codecs.push_back(kCn16000Codec);
1672 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001674 {
ossu20a4b3f2017-04-27 02:08:52 -07001675 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1676 EXPECT_EQ(103, spec.payload_type);
1677 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001678 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
solenberg059fb442016-10-26 05:12:24 -07001680 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001681 {
ossu20a4b3f2017-04-27 02:08:52 -07001682 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1683 EXPECT_EQ(111, spec.payload_type);
1684 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001685 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686}
1687
1688// Test that we handle various ways of specifying bitrate.
1689TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001690 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001691 cricket::AudioSendParameters parameters;
1692 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001694 {
ossu20a4b3f2017-04-27 02:08:52 -07001695 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1696 EXPECT_EQ(103, spec.payload_type);
1697 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1698 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001699 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001701 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001702 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001703 {
ossu20a4b3f2017-04-27 02:08:52 -07001704 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1705 EXPECT_EQ(103, spec.payload_type);
1706 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1707 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001708 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001710 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001711 {
ossu20a4b3f2017-04-27 02:08:52 -07001712 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1713 EXPECT_EQ(103, spec.payload_type);
1714 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1715 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001716 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001720 {
ossu20a4b3f2017-04-27 02:08:52 -07001721 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1722 EXPECT_EQ(0, spec.payload_type);
1723 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1724 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001725 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001726
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001727 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001729 {
ossu20a4b3f2017-04-27 02:08:52 -07001730 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1731 EXPECT_EQ(0, spec.payload_type);
1732 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1733 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001734 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 parameters.codecs[0] = kOpusCodec;
1737 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001739 {
ossu20a4b3f2017-04-27 02:08:52 -07001740 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1741 EXPECT_EQ(111, spec.payload_type);
1742 EXPECT_STREQ("opus", spec.format.name.c_str());
1743 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001744 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745}
1746
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001747// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001748TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001749 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001750 cricket::AudioSendParameters parameters;
1751 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001752}
1753
1754// Test that we can set send codecs even with telephone-event codec as the first
1755// one on the list.
1756TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001757 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001759 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 parameters.codecs.push_back(kIsacCodec);
1761 parameters.codecs.push_back(kPcmuCodec);
1762 parameters.codecs[0].id = 98; // DTMF
1763 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001765 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1766 EXPECT_EQ(96, spec.payload_type);
1767 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001768 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001769}
1770
solenberg31642aa2016-03-14 08:00:37 -07001771// Test that payload type range is limited for telephone-event codec.
1772TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001773 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001774 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001775 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001776 parameters.codecs.push_back(kIsacCodec);
1777 parameters.codecs[0].id = 0; // DTMF
1778 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001779 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001780 EXPECT_TRUE(channel_->CanInsertDtmf());
1781 parameters.codecs[0].id = 128; // DTMF
1782 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1783 EXPECT_FALSE(channel_->CanInsertDtmf());
1784 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001785 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001786 EXPECT_TRUE(channel_->CanInsertDtmf());
1787 parameters.codecs[0].id = -1; // DTMF
1788 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1789 EXPECT_FALSE(channel_->CanInsertDtmf());
1790}
1791
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001792// Test that we can set send codecs even with CN codec as the first
1793// one on the list.
1794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001795 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 cricket::AudioSendParameters parameters;
1797 parameters.codecs.push_back(kCn16000Codec);
1798 parameters.codecs.push_back(kIsacCodec);
1799 parameters.codecs.push_back(kPcmuCodec);
1800 parameters.codecs[0].id = 98; // wideband CN
1801 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001803 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1804 EXPECT_EQ(96, send_codec_spec.payload_type);
1805 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001806 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807}
1808
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001809// Test that we set VAD and DTMF types correctly as caller.
1810TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001811 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 cricket::AudioSendParameters parameters;
1813 parameters.codecs.push_back(kIsacCodec);
1814 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 parameters.codecs.push_back(kCn16000Codec);
1817 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001818 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001819 parameters.codecs[0].id = 96;
1820 parameters.codecs[2].id = 97; // wideband CN
1821 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001822 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001823 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1824 EXPECT_EQ(96, send_codec_spec.payload_type);
1825 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1826 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001827 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001828 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829}
1830
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001831// Test that we set VAD and DTMF types correctly as callee.
1832TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 cricket::AudioSendParameters parameters;
1835 parameters.codecs.push_back(kIsacCodec);
1836 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001837 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 parameters.codecs.push_back(kCn16000Codec);
1839 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001840 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001841 parameters.codecs[0].id = 96;
1842 parameters.codecs[2].id = 97; // wideband CN
1843 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001845 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001846 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001847
ossu20a4b3f2017-04-27 02:08:52 -07001848 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1849 EXPECT_EQ(96, send_codec_spec.payload_type);
1850 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1851 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001852 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001853 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001854}
1855
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001856// Test that we only apply VAD if we have a CN codec that matches the
1857// send codec clockrate.
1858TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001859 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001861 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001862 parameters.codecs.push_back(kIsacCodec);
1863 parameters.codecs.push_back(kCn16000Codec);
1864 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001865 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001866 {
ossu20a4b3f2017-04-27 02:08:52 -07001867 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1868 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1869 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001870 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001871 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001872 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001873 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001875 {
ossu20a4b3f2017-04-27 02:08:52 -07001876 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1877 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001878 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001879 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001880 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001882 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001883 {
ossu20a4b3f2017-04-27 02:08:52 -07001884 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1885 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1886 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001887 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001888 }
Brave Yao5225dd82015-03-26 07:39:19 +08001889 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001891 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001892 {
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001895 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001896 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897}
1898
1899// Test that we perform case-insensitive matching of codec names.
1900TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001901 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001902 cricket::AudioSendParameters parameters;
1903 parameters.codecs.push_back(kIsacCodec);
1904 parameters.codecs.push_back(kPcmuCodec);
1905 parameters.codecs.push_back(kCn16000Codec);
1906 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001907 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001908 parameters.codecs[0].name = "iSaC";
1909 parameters.codecs[0].id = 96;
1910 parameters.codecs[2].id = 97; // wideband CN
1911 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001913 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1914 EXPECT_EQ(96, send_codec_spec.payload_type);
1915 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1916 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001917 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001918 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001919}
1920
stefanba4c0e42016-02-04 04:12:24 -08001921class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1922 public:
1923 WebRtcVoiceEngineWithSendSideBweTest()
1924 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1925};
1926
1927TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1928 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001929 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001930 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001931 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1932 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1933 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001934 extension.id);
1935 return;
1936 }
1937 }
1938 FAIL() << "Transport sequence number extension not in header-extension list.";
1939}
1940
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001941// Test support for audio level header extension.
1942TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001943 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001944}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001945TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001946 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001947}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001948
solenbergd4adce42016-11-17 06:26:52 -08001949// Test support for transport sequence number header extension.
1950TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1951 TestSetSendRtpHeaderExtensions(
1952 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001953}
solenbergd4adce42016-11-17 06:26:52 -08001954TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1955 TestSetRecvRtpHeaderExtensions(
1956 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957}
1958
solenberg1ac56142015-10-13 03:58:19 -07001959// Test that we can create a channel and start sending on it.
1960TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001961 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001962 SetSendParameters(send_parameters_);
1963 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001964 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001965 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001966 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001967}
1968
1969// Test that a channel will send if and only if it has a source and is enabled
1970// for sending.
1971TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001972 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001973 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001974 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001975 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1977 SetAudioSend(kSsrcX, true, &fake_source_);
1978 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1979 SetAudioSend(kSsrcX, true, nullptr);
1980 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001981}
1982
solenberg94218532016-06-16 10:53:22 -07001983// Test that a channel is muted/unmuted.
1984TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1985 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001987 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1988 SetAudioSend(kSsrcX, true, nullptr);
1989 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1990 SetAudioSend(kSsrcX, false, nullptr);
1991 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001992}
1993
solenberg6d6e7c52016-04-13 09:07:30 -07001994// Test that SetSendParameters() does not alter a stream's send state.
1995TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1996 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001998
1999 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002000 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002001 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002002
2003 // Changing RTP header extensions will recreate the AudioSendStream.
2004 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002005 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002007 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002008
2009 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002010 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002011 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002012
2013 // Changing RTP header extensions will recreate the AudioSendStream.
2014 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002015 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002016 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002017}
2018
solenberg1ac56142015-10-13 03:58:19 -07002019// Test that we can create a channel and start playing out on it.
2020TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002021 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002022 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002023 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002024 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002025 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002026 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027}
2028
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029// Test that we can add and remove send streams.
2030TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2031 SetupForMultiSendStream();
2032
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002033 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002034 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035
solenbergc96df772015-10-21 13:01:53 -07002036 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002038 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002039 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002041 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 }
tfarina5237aaf2015-11-10 23:44:30 -08002043 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044
solenbergc96df772015-10-21 13:01:53 -07002045 // Delete the send streams.
2046 for (uint32_t ssrc : kSsrcs4) {
2047 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002048 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002049 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 }
solenbergc96df772015-10-21 13:01:53 -07002051 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052}
2053
2054// Test SetSendCodecs correctly configure the codecs in all send streams.
2055TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2056 SetupForMultiSendStream();
2057
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002059 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002061 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062 }
2063
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002064 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002065 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002066 parameters.codecs.push_back(kIsacCodec);
2067 parameters.codecs.push_back(kCn16000Codec);
2068 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002069 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070
2071 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002072 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002073 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2074 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002075 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2076 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2077 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002078 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 }
2080
minyue7a973442016-10-20 03:27:12 -07002081 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002082 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002084 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002085 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2086 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002087 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2088 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002089 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002090 }
2091}
2092
2093// Test we can SetSend on all send streams correctly.
2094TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2095 SetupForMultiSendStream();
2096
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002097 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002098 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002100 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002101 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002102 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 }
2104
2105 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002106 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002107 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002109 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 }
2111
2112 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002114 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002116 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002117 }
2118}
2119
2120// Test we can set the correct statistics on all send streams.
2121TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2122 SetupForMultiSendStream();
2123
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002125 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002127 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128 }
solenberg85a04962015-10-27 03:35:21 -07002129
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002130 // Create a receive stream to check that none of the send streams end up in
2131 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002132 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002133
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002135 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002136 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002137 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138
solenberg85a04962015-10-27 03:35:21 -07002139 // Check stats for the added streams.
2140 {
2141 cricket::VoiceMediaInfo info;
2142 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002143
solenberg85a04962015-10-27 03:35:21 -07002144 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002145 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002146 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002147 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002148 }
hbos1acfbd22016-11-17 23:43:29 -08002149 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002150
2151 // We have added one receive stream. We should see empty stats.
2152 EXPECT_EQ(info.receivers.size(), 1u);
2153 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002154 }
solenberg1ac56142015-10-13 03:58:19 -07002155
solenberg2100c0b2017-03-01 11:29:29 -08002156 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002157 {
2158 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002159 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002160 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002161 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002162 EXPECT_EQ(0u, info.receivers.size());
2163 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002164
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002165 // Deliver a new packet - a default receive stream should be created and we
2166 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002167 {
2168 cricket::VoiceMediaInfo info;
2169 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2170 SetAudioReceiveStreamStats();
2171 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002172 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002173 EXPECT_EQ(1u, info.receivers.size());
2174 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002175 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002176 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177}
2178
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002179// Test that we can add and remove receive streams, and do proper send/playout.
2180// We can receive on multiple streams while sending one stream.
2181TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002182 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183
solenberg1ac56142015-10-13 03:58:19 -07002184 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002185 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002186 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002187
solenberg1ac56142015-10-13 03:58:19 -07002188 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002189 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002190 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002191 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002192
solenberg1ac56142015-10-13 03:58:19 -07002193 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002194 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002195
2196 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002197 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2198 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2199 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002200
2201 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002202 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002203 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204
2205 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002206 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002207 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2208 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002209
aleloi84ef6152016-08-04 05:28:21 -07002210 // Restart playout and make sure recv streams are played out.
2211 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002212 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2213 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002214
aleloi84ef6152016-08-04 05:28:21 -07002215 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2217 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218}
2219
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002220// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002221// and start sending on it.
2222TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002223 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002224 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002225 EXPECT_CALL(apm_gc_,
2226 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002227 SetSendParameters(send_parameters_);
2228 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002230 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002231 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002232}
2233
wu@webrtc.org97077a32013-10-25 21:18:33 +00002234TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002235 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002236 EXPECT_CALL(adm_,
2237 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002238 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002239 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002240 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002241 send_parameters_.options.tx_agc_target_dbov = 3;
2242 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2243 send_parameters_.options.tx_agc_limiter = true;
2244 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002245 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2246 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2247 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002248 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002249
2250 // Check interaction with adjust_agc_delta. Both should be respected, for
2251 // backwards compatibility.
Oskar Sundbom78807582017-11-16 11:09:55 +01002252 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002253 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002254 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002255}
2256
minyue6b825df2016-10-31 04:08:32 -07002257TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2258 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002259 send_parameters_.options.audio_network_adaptor = true;
2260 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002261 SetSendParameters(send_parameters_);
2262 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002263 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002264}
2265
2266TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2267 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002268 send_parameters_.options.audio_network_adaptor = true;
2269 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002270 SetSendParameters(send_parameters_);
2271 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002272 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002273 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002274 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002275 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002276 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002277}
2278
2279TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2280 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002281 send_parameters_.options.audio_network_adaptor = true;
2282 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002283 SetSendParameters(send_parameters_);
2284 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002285 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002286 const int initial_num = call_.GetNumCreatedSendStreams();
2287 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002288 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002289 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2290 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002291 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002292 // AudioSendStream not expected to be recreated.
2293 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2294 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002295 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002296}
2297
michaelt6672b262017-01-11 10:17:59 -08002298class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2299 : public WebRtcVoiceEngineTestFake {
2300 public:
2301 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2302 : WebRtcVoiceEngineTestFake(
2303 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2304 "Enabled/") {}
2305};
2306
2307TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2308 EXPECT_TRUE(SetupSendStream());
2309 cricket::AudioSendParameters parameters;
2310 parameters.codecs.push_back(kOpusCodec);
2311 SetSendParameters(parameters);
2312 const int initial_num = call_.GetNumCreatedSendStreams();
2313 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2314
2315 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2316 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002317 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2318 constexpr int kMinOverheadBps =
2319 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002320
2321 constexpr int kOpusMinBitrateBps = 6000;
2322 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002323 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002324 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002325 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002326 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002327
Oskar Sundbom78807582017-11-16 11:09:55 +01002328 parameters.options.audio_network_adaptor = true;
2329 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002330 SetSendParameters(parameters);
2331
ossu11bfc532017-02-16 05:37:06 -08002332 constexpr int kMinOverheadWithAnaBps =
2333 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002334
2335 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002336 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002337
minyuececec102017-03-27 13:04:25 -07002338 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002339 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002340}
2341
minyuececec102017-03-27 13:04:25 -07002342// This test is similar to
2343// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2344// additional field trial.
2345TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2346 SetRtpSendParameterUpdatesMaxBitrate) {
2347 EXPECT_TRUE(SetupSendStream());
2348 cricket::AudioSendParameters send_parameters;
2349 send_parameters.codecs.push_back(kOpusCodec);
2350 SetSendParameters(send_parameters);
2351
2352 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2353 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2354 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2355
2356 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002357 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002358 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2359
2360 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2361#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2362 constexpr int kMinOverhead = 3333;
2363#else
2364 constexpr int kMinOverhead = 6666;
2365#endif
2366 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2367}
2368
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002370// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002371TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002372 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002373 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374}
2375
2376TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2377 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002378 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002379 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002380 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002381 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002382 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002383 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002384 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385
solenberg85a04962015-10-27 03:35:21 -07002386 // Check stats for the added streams.
2387 {
2388 cricket::VoiceMediaInfo info;
2389 EXPECT_EQ(true, channel_->GetStats(&info));
2390
2391 // We have added one send stream. We should see the stats we've set.
2392 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002393 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002394 // We have added one receive stream. We should see empty stats.
2395 EXPECT_EQ(info.receivers.size(), 1u);
2396 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2397 }
solenberg1ac56142015-10-13 03:58:19 -07002398
solenberg566ef242015-11-06 15:34:49 -08002399 // Start sending - this affects some reported stats.
2400 {
2401 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002402 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002403 EXPECT_EQ(true, channel_->GetStats(&info));
2404 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002405 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002406 }
2407
solenberg2100c0b2017-03-01 11:29:29 -08002408 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002409 {
2410 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002411 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002412 EXPECT_EQ(true, channel_->GetStats(&info));
2413 EXPECT_EQ(1u, info.senders.size());
2414 EXPECT_EQ(0u, info.receivers.size());
2415 }
solenberg1ac56142015-10-13 03:58:19 -07002416
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002417 // Deliver a new packet - a default receive stream should be created and we
2418 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002419 {
2420 cricket::VoiceMediaInfo info;
2421 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2422 SetAudioReceiveStreamStats();
2423 EXPECT_EQ(true, channel_->GetStats(&info));
2424 EXPECT_EQ(1u, info.senders.size());
2425 EXPECT_EQ(1u, info.receivers.size());
2426 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002427 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002428 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429}
2430
2431// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002432// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002434 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002435 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2436 EXPECT_TRUE(AddRecvStream(kSsrcY));
2437 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438}
2439
2440// Test that the local SSRC is the same on sending and receiving channels if the
2441// receive channel is created before the send channel.
2442TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002443 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002444 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002446 cricket::StreamParams::CreateLegacy(kSsrcX)));
2447 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2448 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449}
2450
2451// Test that we can properly receive packets.
2452TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002453 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002454 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002456
2457 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2458 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459}
2460
2461// Test that we can properly receive packets on multiple streams.
2462TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002463 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002464 const uint32_t ssrc1 = 1;
2465 const uint32_t ssrc2 = 2;
2466 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002467 EXPECT_TRUE(AddRecvStream(ssrc1));
2468 EXPECT_TRUE(AddRecvStream(ssrc2));
2469 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002471 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002472 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002474 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475 }
mflodman3d7db262016-04-29 00:57:13 -07002476
2477 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2478 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2479 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2480
2481 EXPECT_EQ(s1.received_packets(), 0);
2482 EXPECT_EQ(s2.received_packets(), 0);
2483 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_EQ(s1.received_packets(), 0);
2487 EXPECT_EQ(s2.received_packets(), 0);
2488 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002489
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002491 EXPECT_EQ(s1.received_packets(), 1);
2492 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2493 EXPECT_EQ(s2.received_packets(), 0);
2494 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002495
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_EQ(s1.received_packets(), 1);
2498 EXPECT_EQ(s2.received_packets(), 1);
2499 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2500 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002501
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002503 EXPECT_EQ(s1.received_packets(), 1);
2504 EXPECT_EQ(s2.received_packets(), 1);
2505 EXPECT_EQ(s3.received_packets(), 1);
2506 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002507
mflodman3d7db262016-04-29 00:57:13 -07002508 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2509 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2510 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511}
2512
solenberg2100c0b2017-03-01 11:29:29 -08002513// Test that receiving on an unsignaled stream works (a stream is created).
2514TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002515 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002516 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2517
solenberg7e63ef02015-11-20 00:19:43 -08002518 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002519
2520 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2522 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002523}
2524
solenberg2100c0b2017-03-01 11:29:29 -08002525// Test that receiving N unsignaled stream works (streams will be created), and
2526// that packets are forwarded to them all.
2527TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002528 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002529 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002530 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2531
solenberg2100c0b2017-03-01 11:29:29 -08002532 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002533 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002534 rtc::SetBE32(&packet[8], ssrc);
2535 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002536
solenberg2100c0b2017-03-01 11:29:29 -08002537 // Verify we have one new stream for each loop iteration.
2538 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002539 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2540 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002541 }
mflodman3d7db262016-04-29 00:57:13 -07002542
solenberg2100c0b2017-03-01 11:29:29 -08002543 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002544 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002545 rtc::SetBE32(&packet[8], ssrc);
2546 DeliverPacket(packet, sizeof(packet));
2547
solenbergebb349d2017-03-13 05:46:15 -07002548 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002549 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2550 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2551 }
2552
2553 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2554 constexpr uint32_t kAnotherSsrc = 667;
2555 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002556 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002557
2558 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002559 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002560 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002561 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002562 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2563 EXPECT_EQ(2, streams[i]->received_packets());
2564 }
2565 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2566 EXPECT_EQ(1, streams[i]->received_packets());
2567 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002568 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002569}
2570
solenberg2100c0b2017-03-01 11:29:29 -08002571// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002572// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002573TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002574 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002575 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002576 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2577
2578 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002579 const uint32_t signaled_ssrc = 1;
2580 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002581 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002582 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002583 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2584 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002585 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002586
2587 // Note that the first unknown SSRC cannot be 0, because we only support
2588 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002589 const uint32_t unsignaled_ssrc = 7011;
2590 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002591 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002592 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2593 packet, sizeof(packet)));
2594 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2595
2596 DeliverPacket(packet, sizeof(packet));
2597 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2598
2599 rtc::SetBE32(&packet[8], signaled_ssrc);
2600 DeliverPacket(packet, sizeof(packet));
2601 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2602 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002603}
2604
solenberg4904fb62017-02-17 12:01:14 -08002605// Two tests to verify that adding a receive stream with the same SSRC as a
2606// previously added unsignaled stream will only recreate underlying stream
2607// objects if the stream parameters have changed.
2608TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2609 EXPECT_TRUE(SetupChannel());
2610
2611 // Spawn unsignaled stream with SSRC=1.
2612 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2613 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2614 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2615 sizeof(kPcmuFrame)));
2616
2617 // Verify that the underlying stream object in Call is not recreated when a
2618 // stream with SSRC=1 is added.
2619 const auto& streams = call_.GetAudioReceiveStreams();
2620 EXPECT_EQ(1, streams.size());
2621 int audio_receive_stream_id = streams.front()->id();
2622 EXPECT_TRUE(AddRecvStream(1));
2623 EXPECT_EQ(1, streams.size());
2624 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2625}
2626
2627TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2628 EXPECT_TRUE(SetupChannel());
2629
2630 // Spawn unsignaled stream with SSRC=1.
2631 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2632 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2633 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2634 sizeof(kPcmuFrame)));
2635
2636 // Verify that the underlying stream object in Call *is* recreated when a
2637 // stream with SSRC=1 is added, and which has changed stream parameters.
2638 const auto& streams = call_.GetAudioReceiveStreams();
2639 EXPECT_EQ(1, streams.size());
2640 int audio_receive_stream_id = streams.front()->id();
2641 cricket::StreamParams stream_params;
2642 stream_params.ssrcs.push_back(1);
2643 stream_params.sync_label = "sync_label";
2644 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2645 EXPECT_EQ(1, streams.size());
2646 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2647}
2648
solenberg0a617e22015-10-20 15:49:38 -07002649// Test that we properly handle failures to add a receive stream.
2650TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002653 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002654}
2655
solenberg0a617e22015-10-20 15:49:38 -07002656// Test that we properly handle failures to add a send stream.
2657TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002658 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002659 voe_.set_fail_create_channel(true);
2660 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2661}
2662
solenberg1ac56142015-10-13 03:58:19 -07002663// Test that AddRecvStream creates new stream.
2664TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002665 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002666 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002667 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002668 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669}
2670
2671// Test that after adding a recv stream, we do not decode more codecs than
2672// those previously passed into SetRecvCodecs.
2673TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002675 cricket::AudioRecvParameters parameters;
2676 parameters.codecs.push_back(kIsacCodec);
2677 parameters.codecs.push_back(kPcmuCodec);
2678 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002679 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002680 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2681 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2682 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002683}
2684
2685// Test that we properly clean up any streams that were added, even if
2686// not explicitly removed.
2687TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002689 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002690 EXPECT_TRUE(AddRecvStream(1));
2691 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002692 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2693 delete channel_;
2694 channel_ = NULL;
2695 EXPECT_EQ(0, voe_.GetNumChannels());
2696}
2697
wu@webrtc.org78187522013-10-07 23:32:02 +00002698TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002699 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002700 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002701}
2702
2703TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002704 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002705 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002706 // Manually delete channel to simulate a failure.
2707 int channel = voe_.GetLastChannel();
2708 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2709 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002710 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002711 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002712 EXPECT_NE(channel, new_channel);
2713 // The last created channel is deleted too.
2714 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002715}
2716
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002717// Test the InsertDtmf on default send stream as caller.
2718TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002719 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720}
2721
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002722// Test the InsertDtmf on default send stream as callee
2723TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002724 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002725}
2726
2727// Test the InsertDtmf on specified send stream as caller.
2728TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002729 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002730}
2731
2732// Test the InsertDtmf on specified send stream as callee.
2733TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002734 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735}
2736
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002738 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002739 EXPECT_CALL(adm_,
2740 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2741 EXPECT_CALL(adm_,
2742 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2743 EXPECT_CALL(adm_,
2744 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002745
solenberg246b8172015-12-08 09:50:23 -08002746 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2747 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002748
solenberg246b8172015-12-08 09:50:23 -08002749 // Nothing set in AudioOptions, so everything should be as default.
2750 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002752 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002753 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2754 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002755
2756 // Turn echo cancellation off
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.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761
2762 // Turn echo cancellation back on, with settings, and make sure
2763 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002764 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2765 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002766 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002767 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002769 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2770 // control.
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002773 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002775
2776 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002777 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002779 send_parameters_.options.delay_agnostic_aec = false;
2780 send_parameters_.options.extended_filter_aec = false;
2781 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002783
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002784 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002787 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002788 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002789
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002790 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002791 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002794 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002795 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002796 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002797 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002798
2799 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002800 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2802 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002803 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002804 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002805 send_parameters_.options.auto_gain_control = true;
2806 send_parameters_.options.adjust_agc_delta = rtc::nullopt;
solenberg059fb442016-10-26 05:12:24 -07002807 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002808
2809 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002810 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002813 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002814 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002815 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002816 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2817 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2818 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002819 send_parameters_.options.noise_suppression = false;
2820 send_parameters_.options.highpass_filter = false;
2821 send_parameters_.options.typing_detection = false;
2822 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002823 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002824 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825
solenberg1ac56142015-10-13 03:58:19 -07002826 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002827 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2828 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2829 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002830 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002831 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002832 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002833 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2835 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002836 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837}
2838
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002839TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002840 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002841 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002842 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002843 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002844 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002845 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002846 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002847 EXPECT_CALL(adm_,
2848 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2849 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2850 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002851 webrtc::AudioProcessing::Config apm_config;
2852 EXPECT_CALL(*apm_, GetConfig())
2853 .Times(10)
2854 .WillRepeatedly(ReturnPointee(&apm_config));
2855 EXPECT_CALL(*apm_, ApplyConfig(_))
2856 .Times(10)
2857 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002858 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002859
kwiberg686a8ef2016-02-26 03:00:35 -08002860 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002861 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002862 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002863 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002864 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002865 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866
2867 // Have to add a stream to make SetSend work.
2868 cricket::StreamParams stream1;
2869 stream1.ssrcs.push_back(1);
2870 channel1->AddSendStream(stream1);
2871 cricket::StreamParams stream2;
2872 stream2.ssrcs.push_back(2);
2873 channel2->AddSendStream(stream2);
2874
2875 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002876 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002877 parameters_options_all.options.echo_cancellation = true;
2878 parameters_options_all.options.auto_gain_control = true;
2879 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002880 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2881 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2882 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002883 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002884 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002885 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002887 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002888 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002889 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002890 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
2892 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002893 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002894 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002895 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2897 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002898 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002900 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002903 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002904 expected_options.echo_cancellation = true;
2905 expected_options.auto_gain_control = true;
2906 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002907 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002908
2909 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002910 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002911 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002912 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002917 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002919 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002920 expected_options.echo_cancellation = true;
2921 expected_options.auto_gain_control = false;
2922 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002923 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924
solenberg76377c52017-02-21 00:54:31 -08002925 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2926 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2927 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002928 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002930 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002931 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002932 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933
solenberg76377c52017-02-21 00:54:31 -08002934 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2935 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2936 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002937 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002938 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002941 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942
solenberg76377c52017-02-21 00:54:31 -08002943 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2944 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2945 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002946 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002947 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002948 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002949 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002950 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002951
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002953 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2954 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002955 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2956 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002957 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2958 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2959 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002960 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002961 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002962 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002963 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002964 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002965 expected_options.echo_cancellation = true;
2966 expected_options.auto_gain_control = false;
2967 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002968 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002969}
2970
wu@webrtc.orgde305012013-10-31 15:40:38 +00002971// This test verifies DSCP settings are properly applied on voice media channel.
2972TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002973 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002974 cricket::FakeNetworkInterface network_interface;
2975 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002976 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002977
peahb1c9d1d2017-07-25 15:45:24 -07002978 webrtc::AudioProcessing::Config apm_config;
2979 EXPECT_CALL(*apm_, GetConfig())
2980 .Times(3)
2981 .WillRepeatedly(ReturnPointee(&apm_config));
2982 EXPECT_CALL(*apm_, ApplyConfig(_))
2983 .Times(3)
2984 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002985 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002986
solenbergbc37fc82016-04-04 09:54:44 -07002987 channel.reset(
2988 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002989 channel->SetInterface(&network_interface);
2990 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2991 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2992
2993 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002994 channel.reset(
2995 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002996 channel->SetInterface(&network_interface);
2997 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2998
2999 // Verify that setting the option to false resets the
3000 // DiffServCodePoint.
3001 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003002 channel.reset(
3003 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003004 channel->SetInterface(&network_interface);
3005 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3006 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3007
3008 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003009}
3010
solenberg1ac56142015-10-13 03:58:19 -07003011TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003012 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003013 cricket::WebRtcVoiceMediaChannel* media_channel =
3014 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003015 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003017 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003018 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3019 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3020 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003021 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003022 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023}
3024
solenberg1ac56142015-10-13 03:58:19 -07003025TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003026 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003028 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3029 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3030 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003031 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003032 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003033 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3034 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003035 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003036 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003037 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003038 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003039}
3040
solenberg4bac9c52015-10-09 02:32:53 -07003041TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003042 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003043 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003045 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003047 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3048 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3049 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003050}
3051
solenberg2100c0b2017-03-01 11:29:29 -08003052TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003053 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003054
3055 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003056 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003057 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3058
3059 // Should remember the volume "2" which will be set on new unsignaled streams,
3060 // and also set the gain to 2 on existing unsignaled streams.
3061 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3062 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3063
3064 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3065 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3066 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3067 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3068 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3069 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3070
3071 // Setting gain with SSRC=0 should affect all unsignaled streams.
3072 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003073 if (kMaxUnsignaledRecvStreams > 1) {
3074 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3075 }
solenberg2100c0b2017-03-01 11:29:29 -08003076 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3077
3078 // Setting gain on an individual stream affects only that.
3079 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003080 if (kMaxUnsignaledRecvStreams > 1) {
3081 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3082 }
solenberg2100c0b2017-03-01 11:29:29 -08003083 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003084}
3085
pbos8fc7fa72015-07-15 08:02:58 -07003086TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003087 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003088 const std::string kSyncLabel = "AvSyncLabel";
3089
solenbergff976312016-03-30 23:28:51 -07003090 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003091 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3092 sp.sync_label = kSyncLabel;
3093 // Creating two channels to make sure that sync label is set properly for both
3094 // the default voice channel and following ones.
3095 EXPECT_TRUE(channel_->AddRecvStream(sp));
3096 sp.ssrcs[0] += 1;
3097 EXPECT_TRUE(channel_->AddRecvStream(sp));
3098
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003099 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003100 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003101 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003102 << "SyncGroup should be set based on sync_label";
3103 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003104 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003105 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003106}
3107
solenberg3a941542015-11-16 07:34:50 -08003108// TODO(solenberg): Remove, once recv streams are configured through Call.
3109// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003110TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003111 // Test that setting the header extensions results in the expected state
3112 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003113 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003114 ssrcs.push_back(223);
3115 ssrcs.push_back(224);
3116
solenbergff976312016-03-30 23:28:51 -07003117 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003118 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003119 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003120 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003121 cricket::StreamParams::CreateLegacy(ssrc)));
3122 }
3123
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003124 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003125 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003126 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 EXPECT_NE(nullptr, s);
3128 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3129 }
3130
3131 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003132 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003133 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003134 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003135 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003136 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003137 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003138 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 EXPECT_NE(nullptr, s);
3140 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003141 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3142 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 for (const auto& s_ext : s_exts) {
3144 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003145 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 }
3147 }
3148 }
3149 }
3150
3151 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003152 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003153 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003154 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155 EXPECT_NE(nullptr, s);
3156 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3157 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003158}
3159
3160TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3161 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003162 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003163 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003164 static const unsigned char kRtcp[] = {
3165 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3166 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3169 };
jbaucheec21bd2016-03-20 06:15:43 -07003170 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003171
solenbergff976312016-03-30 23:28:51 -07003172 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003173 cricket::WebRtcVoiceMediaChannel* media_channel =
3174 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003175 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003176 EXPECT_TRUE(media_channel->AddRecvStream(
3177 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3178
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003179 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003180 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003181 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003182 EXPECT_EQ(0, s->received_packets());
3183 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3184 EXPECT_EQ(1, s->received_packets());
3185 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3186 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003187}
Minyue2013aec2015-05-13 14:14:42 +02003188
solenberg0a617e22015-10-20 15:49:38 -07003189// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003190// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003191TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003192 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003193 EXPECT_TRUE(AddRecvStream(kSsrcY));
3194 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003195 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003196 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3197 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3198 EXPECT_TRUE(AddRecvStream(kSsrcW));
3199 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003200}
3201
solenberg7602aab2016-11-14 11:30:07 -08003202TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3203 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003204 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003205 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003206 cricket::StreamParams::CreateLegacy(kSsrcY)));
3207 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3208 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3209 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003210 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003211 cricket::StreamParams::CreateLegacy(kSsrcW)));
3212 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3213 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003214}
stefan658910c2015-09-03 05:48:32 -07003215
deadbeef884f5852016-01-15 09:20:04 -08003216TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003217 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003218 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3219 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003220
3221 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003222 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3223 EXPECT_TRUE(AddRecvStream(kSsrcX));
3224 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003225
3226 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003227 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3228 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003229
3230 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003231 channel_->SetRawAudioSink(kSsrcX, nullptr);
3232 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003233}
3234
solenberg2100c0b2017-03-01 11:29:29 -08003235TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003236 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003237 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3238 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003239 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3240 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003241
3242 // Should be able to set a default sink even when no stream exists.
3243 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3244
solenberg2100c0b2017-03-01 11:29:29 -08003245 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3246 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003247 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003248 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003249
3250 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003251 channel_->SetRawAudioSink(kSsrc0, nullptr);
3252 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003253
3254 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003255 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3256 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003257
3258 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003260 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003261 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3262
3263 // Spawn another unsignaled stream - it should be assigned the default sink
3264 // and the previous unsignaled stream should lose it.
3265 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3266 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3267 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3268 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003269 if (kMaxUnsignaledRecvStreams > 1) {
3270 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3271 }
solenberg2100c0b2017-03-01 11:29:29 -08003272 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3273
3274 // Reset the default sink - the second unsignaled stream should lose it.
3275 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003276 if (kMaxUnsignaledRecvStreams > 1) {
3277 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3278 }
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3280
3281 // Try setting the default sink while two streams exists.
3282 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003283 if (kMaxUnsignaledRecvStreams > 1) {
3284 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3285 }
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3287
3288 // Try setting the sink for the first unsignaled stream using its known SSRC.
3289 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003290 if (kMaxUnsignaledRecvStreams > 1) {
3291 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3292 }
solenberg2100c0b2017-03-01 11:29:29 -08003293 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003294 if (kMaxUnsignaledRecvStreams > 1) {
3295 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3296 }
deadbeef884f5852016-01-15 09:20:04 -08003297}
3298
skvlad7a43d252016-03-22 15:32:27 -07003299// Test that, just like the video channel, the voice channel communicates the
3300// network state to the call.
3301TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003302 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003303
3304 EXPECT_EQ(webrtc::kNetworkUp,
3305 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3306 EXPECT_EQ(webrtc::kNetworkUp,
3307 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3308
3309 channel_->OnReadyToSend(false);
3310 EXPECT_EQ(webrtc::kNetworkDown,
3311 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3312 EXPECT_EQ(webrtc::kNetworkUp,
3313 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3314
3315 channel_->OnReadyToSend(true);
3316 EXPECT_EQ(webrtc::kNetworkUp,
3317 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3318 EXPECT_EQ(webrtc::kNetworkUp,
3319 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3320}
3321
aleloi18e0b672016-10-04 02:45:47 -07003322// Test that playout is still started after changing parameters
3323TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3324 SetupRecvStream();
3325 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003326 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003327
3328 // Changing RTP header extensions will recreate the AudioReceiveStream.
3329 cricket::AudioRecvParameters parameters;
3330 parameters.extensions.push_back(
3331 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3332 channel_->SetRecvParameters(parameters);
3333
solenberg2100c0b2017-03-01 11:29:29 -08003334 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003335}
3336
stefan658910c2015-09-03 05:48:32 -07003337// Tests that the library initializes and shuts down properly.
3338TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003339 // If the VoiceEngine wants to gather available codecs early, that's fine but
3340 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003341 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003342 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3343 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003344 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003345 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003346 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003347 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003348 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003349 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003350 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003351 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3352 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003353 EXPECT_TRUE(channel != nullptr);
3354 delete channel;
solenbergff976312016-03-30 23:28:51 -07003355}
stefan658910c2015-09-03 05:48:32 -07003356
solenbergff976312016-03-30 23:28:51 -07003357// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003358TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3359 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003360 EXPECT_CALL(adm, AddRef()).Times(3);
3361 EXPECT_CALL(adm, Release())
3362 .Times(3)
3363 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003364 {
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(
ossueb1fde42017-05-02 06:46:30 -07003368 &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();
skvlad11a9cbf2016-10-07 11:53:05 -07003371 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003372 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003373 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003374 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3375 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3376 EXPECT_TRUE(channel != nullptr);
3377 delete channel;
3378 }
stefan658910c2015-09-03 05:48:32 -07003379}
3380
ossu20a4b3f2017-04-27 02:08:52 -07003381// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3382TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003383 // TODO(ossu): Why are the payload types of codecs with non-static payload
3384 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003385 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003386 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3387 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003388 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003389 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003390 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003391 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003392 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003393 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3394 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3395 (clockrate == 0 || codec.clockrate == clockrate);
3396 };
3397 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003399 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003400 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003401 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003402 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003403 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003404 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003405 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003406 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003407 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003408 EXPECT_EQ(126, codec.id);
3409 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3410 // Remove these checks once both send and receive side assigns payload types
3411 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003412 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003413 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003414 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003415 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003416 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003417 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003418 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003419 EXPECT_EQ(111, codec.id);
3420 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3421 EXPECT_EQ("10", codec.params.find("minptime")->second);
3422 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3423 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003424 }
3425 }
stefan658910c2015-09-03 05:48:32 -07003426}
3427
3428// Tests that VoE supports at least 32 channels
3429TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003430 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003431 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3432 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003433 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003434 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003435 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003436 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003437 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003438 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003439 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003440
3441 cricket::VoiceMediaChannel* channels[32];
3442 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003443 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003444 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3445 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003446 if (!channel)
3447 break;
stefan658910c2015-09-03 05:48:32 -07003448 channels[num_channels++] = channel;
3449 }
3450
tfarina5237aaf2015-11-10 23:44:30 -08003451 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003452 EXPECT_EQ(expected, num_channels);
3453
3454 while (num_channels > 0) {
3455 delete channels[--num_channels];
3456 }
stefan658910c2015-09-03 05:48:32 -07003457}
3458
3459// Test that we set our preferred codecs properly.
3460TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003461 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3462 // - Check that our builtin codecs are usable by Channel.
3463 // - The codecs provided by the engine is usable by Channel.
3464 // It does not check that the codecs in the RecvParameters are actually
3465 // what we sent in - though it's probably reasonable to expect so, if
3466 // SetRecvParameters returns true.
3467 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003468 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003469 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3470 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003471 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003472 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003473 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003474 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003475 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003476 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003477 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003478 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3479 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003480 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003481 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003482 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003483}
ossu9def8002017-02-09 05:14:32 -08003484
3485TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3486 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003487 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3488 {48000, 2, 16000, 10000, 20000}};
3489 spec1.info.allow_comfort_noise = false;
3490 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003491 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003492 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3493 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003494 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003495 specs.push_back(webrtc::AudioCodecSpec{
3496 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3497 {16000, 1, 13300}});
3498 specs.push_back(
3499 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3500 specs.push_back(
3501 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003502
ossueb1fde42017-05-02 06:46:30 -07003503 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3504 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3505 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003506 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003507 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003508 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003509 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003510
peaha9cc40b2017-06-29 08:32:09 -07003511 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3512 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003513 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003514 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003515 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003516 auto codecs = engine.recv_codecs();
3517 EXPECT_EQ(11, codecs.size());
3518
3519 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3520 // check the actual values safely, to provide better test results.
3521 auto get_codec =
3522 [&codecs](size_t index) -> const cricket::AudioCodec& {
3523 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3524 if (codecs.size() > index)
3525 return codecs[index];
3526 return missing_codec;
3527 };
3528
3529 // Ensure the general codecs are generated first and in order.
3530 for (size_t i = 0; i != specs.size(); ++i) {
3531 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3532 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3533 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3534 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3535 }
3536
3537 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003538 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003539 auto find_codec =
3540 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3541 for (size_t i = 0; i != codecs.size(); ++i) {
3542 const cricket::AudioCodec& codec = codecs[i];
3543 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3544 codec.clockrate == format.clockrate_hz &&
3545 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003546 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003547 }
3548 }
3549 return -1;
3550 };
3551
3552 // Ensure all supplementary codecs are generated last. Their internal ordering
3553 // is not important.
3554 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3555 const int num_specs = static_cast<int>(specs.size());
3556 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3557 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3558 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3559 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3560 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3561 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3562 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3563}