blob: b03c8df5b802fd58a0150ad00e0ba7c08c2538b9 [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;
560 stats.aec_quality_min = 9.01f;
561 stats.echo_delay_median_ms = 234;
562 stats.echo_delay_std_ms = 567;
563 stats.echo_return_loss = 890;
564 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700565 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800566 stats.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100567 stats.ana_statistics.bitrate_action_counter = 321;
568 stats.ana_statistics.channel_action_counter = 432;
569 stats.ana_statistics.dtx_action_counter = 543;
570 stats.ana_statistics.fec_action_counter = 654;
571 stats.ana_statistics.frame_length_increase_counter = 765;
572 stats.ana_statistics.frame_length_decrease_counter = 876;
573 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700574 stats.typing_noise_detected = true;
575 return stats;
576 }
577 void SetAudioSendStreamStats() {
578 for (auto* s : call_.GetAudioSendStreams()) {
579 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200580 }
solenberg85a04962015-10-27 03:35:21 -0700581 }
solenberg566ef242015-11-06 15:34:49 -0800582 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
583 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700584 const auto stats = GetAudioSendStreamStats();
585 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
586 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
587 EXPECT_EQ(info.packets_sent, stats.packets_sent);
588 EXPECT_EQ(info.packets_lost, stats.packets_lost);
589 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
590 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800591 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700592 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
593 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
594 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
595 EXPECT_EQ(info.audio_level, stats.audio_level);
596 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
597 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
598 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
599 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
600 EXPECT_EQ(info.echo_return_loss_enhancement,
601 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700602 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800603 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
604 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700605 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
606 stats.ana_statistics.bitrate_action_counter);
607 EXPECT_EQ(info.ana_statistics.channel_action_counter,
608 stats.ana_statistics.channel_action_counter);
609 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
610 stats.ana_statistics.dtx_action_counter);
611 EXPECT_EQ(info.ana_statistics.fec_action_counter,
612 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700613 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
614 stats.ana_statistics.frame_length_increase_counter);
615 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
616 stats.ana_statistics.frame_length_decrease_counter);
617 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
618 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800619 EXPECT_EQ(info.typing_noise_detected,
620 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700621 }
622
623 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
624 webrtc::AudioReceiveStream::Stats stats;
625 stats.remote_ssrc = 123;
626 stats.bytes_rcvd = 456;
627 stats.packets_rcvd = 768;
628 stats.packets_lost = 101;
629 stats.fraction_lost = 23.45f;
630 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100631 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700632 stats.ext_seqnum = 678;
633 stats.jitter_ms = 901;
634 stats.jitter_buffer_ms = 234;
635 stats.jitter_buffer_preferred_ms = 567;
636 stats.delay_estimate_ms = 890;
637 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700638 stats.total_samples_received = 5678901;
639 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200640 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200641 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700642 stats.expand_rate = 5.67f;
643 stats.speech_expand_rate = 8.90f;
644 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200645 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700646 stats.accelerate_rate = 4.56f;
647 stats.preemptive_expand_rate = 7.89f;
648 stats.decoding_calls_to_silence_generator = 12;
649 stats.decoding_calls_to_neteq = 345;
650 stats.decoding_normal = 67890;
651 stats.decoding_plc = 1234;
652 stats.decoding_cng = 5678;
653 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700654 stats.decoding_muted_output = 3456;
655 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200656 return stats;
657 }
658 void SetAudioReceiveStreamStats() {
659 for (auto* s : call_.GetAudioReceiveStreams()) {
660 s->SetStats(GetAudioReceiveStreamStats());
661 }
662 }
663 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700664 const auto stats = GetAudioReceiveStreamStats();
665 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
666 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
667 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
668 EXPECT_EQ(info.packets_lost, stats.packets_lost);
669 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
670 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800671 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700672 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
673 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
674 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200675 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700676 stats.jitter_buffer_preferred_ms);
677 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
678 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700679 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
680 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200681 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200682 EXPECT_EQ(info.jitter_buffer_delay_seconds,
683 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700684 EXPECT_EQ(info.expand_rate, stats.expand_rate);
685 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
686 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200687 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700688 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
689 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200690 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700691 stats.decoding_calls_to_silence_generator);
692 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
693 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
694 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
695 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
696 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700697 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700698 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200699 }
hbos1acfbd22016-11-17 23:43:29 -0800700 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
701 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
702 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
703 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
704 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
705 codec.ToCodecParameters());
706 }
707 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
708 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
709 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
710 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
711 codec.ToCodecParameters());
712 }
713 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200714
peah8271d042016-11-22 07:24:52 -0800715 bool IsHighPassFilterEnabled() {
716 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
717 }
718
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700720 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700721 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800722 webrtc::test::MockGainControl& apm_gc_;
723 webrtc::test::MockEchoCancellation& apm_ec_;
724 webrtc::test::MockNoiseSuppression& apm_ns_;
725 webrtc::test::MockVoiceDetection& apm_vd_;
726 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700727 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200728 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700730 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700731 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200732 cricket::AudioSendParameters send_parameters_;
733 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800734 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700735 webrtc::AudioProcessing::Config apm_config_;
736
stefanba4c0e42016-02-04 04:12:24 -0800737 private:
738 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000739};
740
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741// Tests that we can create and destroy a channel.
742TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700743 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744}
745
solenberg31fec402016-05-06 02:13:12 -0700746// Test that we can add a send stream and that it has the correct defaults.
747TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
748 EXPECT_TRUE(SetupChannel());
749 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800750 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
751 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
752 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700753 EXPECT_EQ("", config.rtp.c_name);
754 EXPECT_EQ(0u, config.rtp.extensions.size());
755 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
756 config.send_transport);
757}
758
759// Test that we can add a receive stream and that it has the correct defaults.
760TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
761 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800762 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700763 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800764 GetRecvStreamConfig(kSsrcX);
765 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700766 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
767 EXPECT_FALSE(config.rtp.transport_cc);
768 EXPECT_EQ(0u, config.rtp.extensions.size());
769 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
770 config.rtcp_send_transport);
771 EXPECT_EQ("", config.sync_group);
772}
773
stefanba4c0e42016-02-04 04:12:24 -0800774TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700775 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800776 bool opus_found = false;
777 for (cricket::AudioCodec codec : codecs) {
778 if (codec.name == "opus") {
779 EXPECT_TRUE(HasTransportCc(codec));
780 opus_found = true;
781 }
782 }
783 EXPECT_TRUE(opus_found);
784}
785
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786// Test that we set our inbound codecs properly, including changing PT.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
791 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800792 parameters.codecs.push_back(kTelephoneEventCodec1);
793 parameters.codecs.push_back(kTelephoneEventCodec2);
794 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 parameters.codecs[2].id = 126;
796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700798 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
799 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
800 {{0, {"PCMU", 8000, 1}},
801 {106, {"ISAC", 16000, 1}},
802 {126, {"telephone-event", 8000, 1}},
803 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that we fail to set an unknown inbound codec.
807TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700808 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200809 cricket::AudioRecvParameters parameters;
810 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700811 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813}
814
815// Test that we fail if we have duplicate types in the inbound list.
816TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 cricket::AudioRecvParameters parameters;
819 parameters.codecs.push_back(kIsacCodec);
820 parameters.codecs.push_back(kCn16000Codec);
821 parameters.codecs[1].id = kIsacCodec.id;
822 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that we can decode OPUS without stereo parameters.
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
830 parameters.codecs.push_back(kPcmuCodec);
831 parameters.codecs.push_back(kOpusCodec);
832 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800833 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700834 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
835 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
836 {{0, {"PCMU", 8000, 1}},
837 {103, {"ISAC", 16000, 1}},
838 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that we can decode OPUS with stereo = 0.
842TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 cricket::AudioRecvParameters parameters;
845 parameters.codecs.push_back(kIsacCodec);
846 parameters.codecs.push_back(kPcmuCodec);
847 parameters.codecs.push_back(kOpusCodec);
848 parameters.codecs[2].params["stereo"] = "0";
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800850 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700851 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
852 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
853 {{0, {"PCMU", 8000, 1}},
854 {103, {"ISAC", 16000, 1}},
855 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we can decode OPUS with stereo = 1.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kPcmuCodec);
864 parameters.codecs.push_back(kOpusCodec);
865 parameters.codecs[2].params["stereo"] = "1";
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800867 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700868 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {103, {"ISAC", 16000, 1}},
872 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000873}
874
875// Test that changes to recv codecs are applied to all streams.
876TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700877 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs.push_back(kTelephoneEventCodec1);
882 parameters.codecs.push_back(kTelephoneEventCodec2);
883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 parameters.codecs[2].id = 126;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700886 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
887 EXPECT_TRUE(AddRecvStream(ssrc));
888 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
889 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
890 {{0, {"PCMU", 8000, 1}},
891 {106, {"ISAC", 16000, 1}},
892 {126, {"telephone-event", 8000, 1}},
893 {107, {"telephone-event", 32000, 1}}})));
894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895}
896
897TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700898 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 cricket::AudioRecvParameters parameters;
900 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800901 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
solenberg2100c0b2017-03-01 11:29:29 -0800904 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800905 ASSERT_EQ(1, dm.count(106));
906 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907}
908
909// Test that we can apply the same set of codecs again while playing.
910TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700911 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 cricket::AudioRecvParameters parameters;
913 parameters.codecs.push_back(kIsacCodec);
914 parameters.codecs.push_back(kCn16000Codec);
915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700916 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
deadbeefcb383672017-04-26 16:28:42 -0700919 // Remapping a payload type to a different codec should fail.
920 parameters.codecs[0] = kOpusCodec;
921 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
926// Test that we can add a codec while playing.
927TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700928 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 parameters.codecs.push_back(kCn16000Codec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700933 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200935 parameters.codecs.push_back(kOpusCodec);
936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800937 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
deadbeefcb383672017-04-26 16:28:42 -0700940// Test that we accept adding the same codec with a different payload type.
941// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
942TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
943 EXPECT_TRUE(SetupRecvStream());
944 cricket::AudioRecvParameters parameters;
945 parameters.codecs.push_back(kIsacCodec);
946 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
947
948 ++parameters.codecs[0].id;
949 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
950}
951
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700953 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955 // Test that when autobw is enabled, bitrate is kept as the default
956 // value. autobw is enabled for the following tests because the target
957 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
959 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
962 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
ossu20a4b3f2017-04-27 02:08:52 -0700965 // opus, default bitrate == 32000 in mono.
966 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700973 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
974 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700975 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700978 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
979 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
980 // Rates above the max (510000) should be capped.
981 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982}
983
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700985 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000986
987 // Test that we can only set a maximum bitrate for a fixed-rate codec
988 // if it's bigger than the fixed rate.
989
990 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700991 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
992 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
993 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
994 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
995 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
996 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
997 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000998}
999
1000TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001001 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001002 const int kDesiredBitrate = 128000;
1003 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001004 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001005 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001007
1008 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001009 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001010
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001012}
1013
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014// Test that bitrate cannot be set for CBR codecs.
1015// Bitrate is ignored if it is higher than the fixed bitrate.
1016// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001017TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001018 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
1020 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001021 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001022 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001023
1024 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001025 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001026 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001027
1028 send_parameters_.max_bandwidth_bps = 128;
1029 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001030 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031}
1032
skvlade0d46372016-04-07 22:59:22 -07001033// Test that the per-stream bitrate limit and the global
1034// bitrate limit both apply.
1035TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1036 EXPECT_TRUE(SetupSendStream());
1037
ossu20a4b3f2017-04-27 02:08:52 -07001038 // opus, default bitrate == 32000.
1039 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001040 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1041 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1042 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1043
1044 // CBR codecs allow both maximums to exceed the bitrate.
1045 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1046 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1047 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1048 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1049
1050 // CBR codecs don't allow per stream maximums to be too low.
1051 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1053}
1054
1055// Test that an attempt to set RtpParameters for a stream that does not exist
1056// fails.
1057TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1058 EXPECT_TRUE(SetupChannel());
1059 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001060 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001061 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1062
1063 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001065}
1066
1067TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001068 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001069 // This test verifies that setting RtpParameters succeeds only if
1070 // the structure contains exactly one encoding.
1071 // TODO(skvlad): Update this test when we start supporting setting parameters
1072 // for each encoding individually.
1073
1074 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001075 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001076 // Two or more encodings should result in failure.
1077 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001079 // Zero encodings should also fail.
1080 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001081 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001082}
1083
1084// Changing the SSRC through RtpParameters is not allowed.
1085TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1086 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001087 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001088 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001089 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001090}
1091
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001093// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001094TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1095 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001096 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001097 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001099 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001100 ASSERT_EQ(1u, parameters.encodings.size());
1101 ASSERT_TRUE(parameters.encodings[0].active);
1102 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1104 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105
1106 // Now change it back to active and verify we resume sending.
1107 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001108 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1109 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001110}
1111
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112// Test that SetRtpSendParameters configures the correct encoding channel for
1113// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001114TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1115 SetupForMultiSendStream();
1116 // Create send streams.
1117 for (uint32_t ssrc : kSsrcs4) {
1118 EXPECT_TRUE(
1119 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1120 }
1121 // Configure one stream to be limited by the stream config, another to be
1122 // limited by the global max, and the third one with no per-stream limit
1123 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001124 SetGlobalMaxBitrate(kOpusCodec, 32000);
1125 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1126 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001127 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1128
ossu20a4b3f2017-04-27 02:08:52 -07001129 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1130 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1131 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001132
1133 // Remove the global cap; the streams should switch to their respective
1134 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001135 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001136 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1137 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1138 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001139}
1140
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001141// Test that GetRtpSendParameters returns the currently configured codecs.
1142TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143 EXPECT_TRUE(SetupSendStream());
1144 cricket::AudioSendParameters parameters;
1145 parameters.codecs.push_back(kIsacCodec);
1146 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001147 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148
solenberg2100c0b2017-03-01 11:29:29 -08001149 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1152 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001153}
1154
deadbeefcb443432016-12-12 11:12:36 -08001155// Test that GetRtpSendParameters returns an SSRC.
1156TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1157 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001158 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001159 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001160 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001161}
1162
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001163// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165 EXPECT_TRUE(SetupSendStream());
1166 cricket::AudioSendParameters parameters;
1167 parameters.codecs.push_back(kIsacCodec);
1168 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001169 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170
solenberg2100c0b2017-03-01 11:29:29 -08001171 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001172
1173 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001174 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001176 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001177 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1178 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001179}
1180
minyuececec102017-03-27 13:04:25 -07001181// Test that max_bitrate_bps in send stream config gets updated correctly when
1182// SetRtpSendParameters is called.
1183TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1184 webrtc::test::ScopedFieldTrials override_field_trials(
1185 "WebRTC-Audio-SendSideBwe/Enabled/");
1186 EXPECT_TRUE(SetupSendStream());
1187 cricket::AudioSendParameters send_parameters;
1188 send_parameters.codecs.push_back(kOpusCodec);
1189 SetSendParameters(send_parameters);
1190
1191 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1192 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1193 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1194
1195 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001196 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001197 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1198
1199 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1200 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1201}
1202
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001203// Test that GetRtpReceiveParameters returns the currently configured codecs.
1204TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1205 EXPECT_TRUE(SetupRecvStream());
1206 cricket::AudioRecvParameters parameters;
1207 parameters.codecs.push_back(kIsacCodec);
1208 parameters.codecs.push_back(kPcmuCodec);
1209 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1210
1211 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001212 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1214 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1215 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1216}
1217
deadbeefcb443432016-12-12 11:12:36 -08001218// Test that GetRtpReceiveParameters returns an SSRC.
1219TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1220 EXPECT_TRUE(SetupRecvStream());
1221 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001222 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001223 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001224 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001225}
1226
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001227// Test that if we set/get parameters multiple times, we get the same results.
1228TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1229 EXPECT_TRUE(SetupRecvStream());
1230 cricket::AudioRecvParameters parameters;
1231 parameters.codecs.push_back(kIsacCodec);
1232 parameters.codecs.push_back(kPcmuCodec);
1233 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1234
1235 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001236 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001237
1238 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001239 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001240
1241 // ... And this shouldn't change the params returned by
1242 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001243 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1244 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001245}
1246
deadbeef3bc15102017-04-20 19:25:07 -07001247// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1248// aren't signaled. It should return an empty "RtpEncodingParameters" when
1249// configured to receive an unsignaled stream and no packets have been received
1250// yet, and start returning the SSRC once a packet has been received.
1251TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1252 ASSERT_TRUE(SetupChannel());
1253 // Call necessary methods to configure receiving a default stream as
1254 // soon as it arrives.
1255 cricket::AudioRecvParameters parameters;
1256 parameters.codecs.push_back(kIsacCodec);
1257 parameters.codecs.push_back(kPcmuCodec);
1258 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1259
1260 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1261 // stream. Should return nothing.
1262 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1263
1264 // Set a sink for an unsignaled stream.
1265 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1266 // Value of "0" means "unsignaled stream".
1267 channel_->SetRawAudioSink(0, std::move(fake_sink));
1268
1269 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1270 // in this method means "unsignaled stream".
1271 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1272 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1273 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1274
1275 // Receive PCMU packet (SSRC=1).
1276 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1277
1278 // The |ssrc| member should still be unset.
1279 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1280 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1281 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1282}
1283
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284// Test that we apply codecs properly.
1285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001286 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001287 cricket::AudioSendParameters parameters;
1288 parameters.codecs.push_back(kIsacCodec);
1289 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001290 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001291 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001292 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001293 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001294 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1295 EXPECT_EQ(96, send_codec_spec.payload_type);
1296 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1297 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1298 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001299 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001300 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
ossu20a4b3f2017-04-27 02:08:52 -07001303// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1304// AudioSendStream.
1305TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001306 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 cricket::AudioSendParameters parameters;
1308 parameters.codecs.push_back(kIsacCodec);
1309 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001310 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 parameters.codecs[0].id = 96;
1312 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001313 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001314 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001315 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001316 // Calling SetSendCodec again with same codec which is already set.
1317 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001318 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001319 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001320}
1321
ossu20a4b3f2017-04-27 02:08:52 -07001322// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1323// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001324
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001325// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001327 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 cricket::AudioSendParameters parameters;
1329 parameters.codecs.push_back(kOpusCodec);
1330 parameters.codecs[0].bitrate = 0;
1331 parameters.codecs[0].clockrate = 50000;
1332 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001335// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].channels = 0;
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001345// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
1351 parameters.codecs[0].channels = 0;
1352 parameters.codecs[0].params["stereo"] = "1";
1353 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
1356// Test that if channel is 1 for opus and there's no stereo, we fail.
1357TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001358 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 cricket::AudioSendParameters parameters;
1360 parameters.codecs.push_back(kOpusCodec);
1361 parameters.codecs[0].bitrate = 0;
1362 parameters.codecs[0].channels = 1;
1363 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001364}
1365
1366// Test that if channel is 1 for opus and stereo=0, we fail.
1367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001368 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 cricket::AudioSendParameters parameters;
1370 parameters.codecs.push_back(kOpusCodec);
1371 parameters.codecs[0].bitrate = 0;
1372 parameters.codecs[0].channels = 1;
1373 parameters.codecs[0].params["stereo"] = "0";
1374 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375}
1376
1377// Test that if channel is 1 for opus and stereo=1, we fail.
1378TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001379 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 cricket::AudioSendParameters parameters;
1381 parameters.codecs.push_back(kOpusCodec);
1382 parameters.codecs[0].bitrate = 0;
1383 parameters.codecs[0].channels = 1;
1384 parameters.codecs[0].params["stereo"] = "1";
1385 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386}
1387
ossu20a4b3f2017-04-27 02:08:52 -07001388// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001390 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 cricket::AudioSendParameters parameters;
1392 parameters.codecs.push_back(kOpusCodec);
1393 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001394 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001395 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396}
1397
ossu20a4b3f2017-04-27 02:08:52 -07001398// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].bitrate = 0;
1404 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407}
1408
ossu20a4b3f2017-04-27 02:08:52 -07001409// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001415 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001418 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001419
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423}
1424
ossu20a4b3f2017-04-27 02:08:52 -07001425// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 0;
1431 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434}
1435
ossu20a4b3f2017-04-27 02:08:52 -07001436// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001438 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001439 cricket::AudioSendParameters parameters;
1440 parameters.codecs.push_back(kOpusCodec);
1441 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001442 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001446
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001448 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001449 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001450}
1451
ossu20a4b3f2017-04-27 02:08:52 -07001452// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001454 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 cricket::AudioSendParameters parameters;
1456 parameters.codecs.push_back(kOpusCodec);
1457 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001458 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001459 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1460 EXPECT_EQ(111, spec.payload_type);
1461 EXPECT_EQ(96000, spec.target_bitrate_bps);
1462 EXPECT_EQ("opus", spec.format.name);
1463 EXPECT_EQ(2, spec.format.num_channels);
1464 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465}
1466
ossu20a4b3f2017-04-27 02:08:52 -07001467// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].bitrate = 30000;
1473 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001474 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001475 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476}
1477
ossu20a4b3f2017-04-27 02:08:52 -07001478// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001484 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001485 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001486}
1487
ossu20a4b3f2017-04-27 02:08:52 -07001488// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001489TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001490 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001491 cricket::AudioSendParameters parameters;
1492 parameters.codecs.push_back(kOpusCodec);
1493 parameters.codecs[0].bitrate = 30000;
1494 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001495 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001496 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001497}
1498
stefan13f1a0a2016-11-30 07:22:58 -08001499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1500 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1501 200000);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1505 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1506}
1507
1508TEST_F(WebRtcVoiceEngineTestFake,
1509 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1510 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1511}
1512
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1514 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1515}
1516
1517TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001518 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001519 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1520 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001521 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001522 SetSendParameters(send_parameters_);
1523 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1524 << "Setting max bitrate should keep previous min bitrate.";
1525 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1526 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001527 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001528}
1529
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001530// Test that we can enable NACK with opus as caller.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541}
1542
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001543// Test that we can enable NACK with opus as callee.
1544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].AddFeedbackParam(
1549 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1550 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001553 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001555
1556 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001557 cricket::StreamParams::CreateLegacy(kSsrcX)));
1558 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001559}
1560
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561// Test that we can enable NACK on receive streams.
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001565 cricket::AudioSendParameters parameters;
1566 parameters.codecs.push_back(kOpusCodec);
1567 parameters.codecs[0].AddFeedbackParam(
1568 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1569 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001570 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1571 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1574 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575}
1576
1577// Test that we can disable NACK.
1578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].AddFeedbackParam(
1583 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1584 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001585 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001586 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 parameters.codecs.clear();
1589 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
1594// Test that we can disable NACK on receive streams.
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].AddFeedbackParam(
1601 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1602 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 parameters.codecs.clear();
1608 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1611 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
1614// Test that NACK is enabled on a new receive stream.
1615TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 cricket::AudioSendParameters parameters;
1618 parameters.codecs.push_back(kIsacCodec);
1619 parameters.codecs.push_back(kCn16000Codec);
1620 parameters.codecs[0].AddFeedbackParam(
1621 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1622 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001625
solenberg2100c0b2017-03-01 11:29:29 -08001626 EXPECT_TRUE(AddRecvStream(kSsrcY));
1627 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1628 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1629 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001630}
1631
stefanba4c0e42016-02-04 04:12:24 -08001632TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001633 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001634 cricket::AudioSendParameters send_parameters;
1635 send_parameters.codecs.push_back(kOpusCodec);
1636 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001638
1639 cricket::AudioRecvParameters recv_parameters;
1640 recv_parameters.codecs.push_back(kIsacCodec);
1641 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001642 EXPECT_TRUE(AddRecvStream(kSsrcX));
1643 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001644 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001645 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001646
ossudedfd282016-06-14 07:12:39 -07001647 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001649 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001650 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001651 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001652}
1653
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001654// Test that we can switch back and forth between Opus and ISAC with CN.
1655TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001656 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001657
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters opus_parameters;
1659 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001661 {
ossu20a4b3f2017-04-27 02:08:52 -07001662 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1663 EXPECT_EQ(111, spec.payload_type);
1664 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001665 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 cricket::AudioSendParameters isac_parameters;
1668 isac_parameters.codecs.push_back(kIsacCodec);
1669 isac_parameters.codecs.push_back(kCn16000Codec);
1670 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001671 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001672 {
ossu20a4b3f2017-04-27 02:08:52 -07001673 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1674 EXPECT_EQ(103, spec.payload_type);
1675 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001676 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001679 {
ossu20a4b3f2017-04-27 02:08:52 -07001680 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1681 EXPECT_EQ(111, spec.payload_type);
1682 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684}
1685
1686// Test that we handle various ways of specifying bitrate.
1687TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(103, spec.payload_type);
1695 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1696 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001697 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001700 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001701 {
ossu20a4b3f2017-04-27 02:08:52 -07001702 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1703 EXPECT_EQ(103, spec.payload_type);
1704 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1705 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001706 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001707 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001708 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001709 {
ossu20a4b3f2017-04-27 02:08:52 -07001710 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1711 EXPECT_EQ(103, spec.payload_type);
1712 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1713 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001714 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001716 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001717 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001718 {
ossu20a4b3f2017-04-27 02:08:52 -07001719 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1720 EXPECT_EQ(0, spec.payload_type);
1721 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1722 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001723 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001725 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001726 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001727 {
ossu20a4b3f2017-04-27 02:08:52 -07001728 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1729 EXPECT_EQ(0, spec.payload_type);
1730 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1731 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001732 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001733
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 parameters.codecs[0] = kOpusCodec;
1735 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001736 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001737 {
ossu20a4b3f2017-04-27 02:08:52 -07001738 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1739 EXPECT_EQ(111, spec.payload_type);
1740 EXPECT_STREQ("opus", spec.format.name.c_str());
1741 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001742 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743}
1744
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001745// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001746TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001747 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 cricket::AudioSendParameters parameters;
1749 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001750}
1751
1752// Test that we can set send codecs even with telephone-event codec as the first
1753// one on the list.
1754TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001755 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001757 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 parameters.codecs.push_back(kIsacCodec);
1759 parameters.codecs.push_back(kPcmuCodec);
1760 parameters.codecs[0].id = 98; // DTMF
1761 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001763 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1764 EXPECT_EQ(96, spec.payload_type);
1765 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001766 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001767}
1768
solenberg31642aa2016-03-14 08:00:37 -07001769// Test that payload type range is limited for telephone-event codec.
1770TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001771 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001772 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001773 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001774 parameters.codecs.push_back(kIsacCodec);
1775 parameters.codecs[0].id = 0; // DTMF
1776 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001778 EXPECT_TRUE(channel_->CanInsertDtmf());
1779 parameters.codecs[0].id = 128; // DTMF
1780 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1781 EXPECT_FALSE(channel_->CanInsertDtmf());
1782 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001783 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001784 EXPECT_TRUE(channel_->CanInsertDtmf());
1785 parameters.codecs[0].id = -1; // DTMF
1786 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1787 EXPECT_FALSE(channel_->CanInsertDtmf());
1788}
1789
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001790// Test that we can set send codecs even with CN codec as the first
1791// one on the list.
1792TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001793 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001794 cricket::AudioSendParameters parameters;
1795 parameters.codecs.push_back(kCn16000Codec);
1796 parameters.codecs.push_back(kIsacCodec);
1797 parameters.codecs.push_back(kPcmuCodec);
1798 parameters.codecs[0].id = 98; // wideband CN
1799 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001800 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(96, send_codec_spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001804 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805}
1806
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001807// Test that we set VAD and DTMF types correctly as caller.
1808TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001809 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001810 cricket::AudioSendParameters parameters;
1811 parameters.codecs.push_back(kIsacCodec);
1812 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 parameters.codecs.push_back(kCn16000Codec);
1815 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001816 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001817 parameters.codecs[0].id = 96;
1818 parameters.codecs[2].id = 97; // wideband CN
1819 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_EQ(96, send_codec_spec.payload_type);
1823 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1824 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001825 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001826 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827}
1828
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001829// Test that we set VAD and DTMF types correctly as callee.
1830TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001832 cricket::AudioSendParameters parameters;
1833 parameters.codecs.push_back(kIsacCodec);
1834 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001835 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs.push_back(kCn16000Codec);
1837 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001838 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 parameters.codecs[0].id = 96;
1840 parameters.codecs[2].id = 97; // wideband CN
1841 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001842 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001843 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001844 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001845
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_EQ(96, send_codec_spec.payload_type);
1848 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1849 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001850 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001851 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001852}
1853
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854// Test that we only apply VAD if we have a CN codec that matches the
1855// send codec clockrate.
1856TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001857 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 parameters.codecs.push_back(kIsacCodec);
1861 parameters.codecs.push_back(kCn16000Codec);
1862 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001864 {
ossu20a4b3f2017-04-27 02:08:52 -07001865 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1866 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1867 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001868 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001869 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001870 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001873 {
ossu20a4b3f2017-04-27 02:08:52 -07001874 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1875 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001876 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001877 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001879 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001880 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001881 {
ossu20a4b3f2017-04-27 02:08:52 -07001882 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1883 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1884 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001885 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001886 }
Brave Yao5225dd82015-03-26 07:39:19 +08001887 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001890 {
ossu20a4b3f2017-04-27 02:08:52 -07001891 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1892 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001893 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001895}
1896
1897// Test that we perform case-insensitive matching of codec names.
1898TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001899 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 cricket::AudioSendParameters parameters;
1901 parameters.codecs.push_back(kIsacCodec);
1902 parameters.codecs.push_back(kPcmuCodec);
1903 parameters.codecs.push_back(kCn16000Codec);
1904 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001905 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 parameters.codecs[0].name = "iSaC";
1907 parameters.codecs[0].id = 96;
1908 parameters.codecs[2].id = 97; // wideband CN
1909 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001910 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001911 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1912 EXPECT_EQ(96, send_codec_spec.payload_type);
1913 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1914 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001915 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001916 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917}
1918
stefanba4c0e42016-02-04 04:12:24 -08001919class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1920 public:
1921 WebRtcVoiceEngineWithSendSideBweTest()
1922 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1923};
1924
1925TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1926 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001927 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001928 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001929 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1930 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1931 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001932 extension.id);
1933 return;
1934 }
1935 }
1936 FAIL() << "Transport sequence number extension not in header-extension list.";
1937}
1938
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001939// Test support for audio level header extension.
1940TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001941 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001942}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001943TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001944 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001945}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001946
solenbergd4adce42016-11-17 06:26:52 -08001947// Test support for transport sequence number header extension.
1948TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1949 TestSetSendRtpHeaderExtensions(
1950 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001951}
solenbergd4adce42016-11-17 06:26:52 -08001952TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1953 TestSetRecvRtpHeaderExtensions(
1954 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955}
1956
solenberg1ac56142015-10-13 03:58:19 -07001957// Test that we can create a channel and start sending on it.
1958TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001959 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(send_parameters_);
1961 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001962 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001963 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001964 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001965}
1966
1967// Test that a channel will send if and only if it has a source and is enabled
1968// for sending.
1969TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001972 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001973 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001974 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1975 SetAudioSend(kSsrcX, true, &fake_source_);
1976 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1977 SetAudioSend(kSsrcX, true, nullptr);
1978 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001979}
1980
solenberg94218532016-06-16 10:53:22 -07001981// Test that a channel is muted/unmuted.
1982TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1983 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1986 SetAudioSend(kSsrcX, true, nullptr);
1987 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1988 SetAudioSend(kSsrcX, false, nullptr);
1989 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001990}
1991
solenberg6d6e7c52016-04-13 09:07:30 -07001992// Test that SetSendParameters() does not alter a stream's send state.
1993TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1994 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996
1997 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001998 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001999 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002000
2001 // Changing RTP header extensions will recreate the AudioSendStream.
2002 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002003 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002005 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002006
2007 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002008 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002009 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002010
2011 // Changing RTP header extensions will recreate the AudioSendStream.
2012 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002013 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002014 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002015}
2016
solenberg1ac56142015-10-13 03:58:19 -07002017// Test that we can create a channel and start playing out on it.
2018TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002019 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002020 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002021 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002022 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002023 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002024 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002025}
2026
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027// Test that we can add and remove send streams.
2028TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2029 SetupForMultiSendStream();
2030
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002032 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002033
solenbergc96df772015-10-21 13:01:53 -07002034 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002036 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002037 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002039 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 }
tfarina5237aaf2015-11-10 23:44:30 -08002041 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042
solenbergc96df772015-10-21 13:01:53 -07002043 // Delete the send streams.
2044 for (uint32_t ssrc : kSsrcs4) {
2045 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002046 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002047 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 }
solenbergc96df772015-10-21 13:01:53 -07002049 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050}
2051
2052// Test SetSendCodecs correctly configure the codecs in all send streams.
2053TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2054 SetupForMultiSendStream();
2055
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002056 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002057 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002059 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 }
2061
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002062 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002064 parameters.codecs.push_back(kIsacCodec);
2065 parameters.codecs.push_back(kCn16000Codec);
2066 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068
2069 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002070 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002071 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2072 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002073 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2074 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2075 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002076 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002077 }
2078
minyue7a973442016-10-20 03:27:12 -07002079 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002080 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002081 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002082 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002083 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2084 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002085 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2086 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002087 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089}
2090
2091// Test we can SetSend on all send streams correctly.
2092TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2093 SetupForMultiSendStream();
2094
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002095 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002096 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002098 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002099 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002100 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 }
2102
2103 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002104 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002105 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002107 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 }
2109
2110 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002111 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002112 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002114 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002115 }
2116}
2117
2118// Test we can set the correct statistics on all send streams.
2119TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2120 SetupForMultiSendStream();
2121
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002123 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002125 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126 }
solenberg85a04962015-10-27 03:35:21 -07002127
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002128 // Create a receive stream to check that none of the send streams end up in
2129 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002133 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002134 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002135 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002136
solenberg85a04962015-10-27 03:35:21 -07002137 // Check stats for the added streams.
2138 {
2139 cricket::VoiceMediaInfo info;
2140 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141
solenberg85a04962015-10-27 03:35:21 -07002142 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002143 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002144 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002145 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002146 }
hbos1acfbd22016-11-17 23:43:29 -08002147 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002148
2149 // We have added one receive stream. We should see empty stats.
2150 EXPECT_EQ(info.receivers.size(), 1u);
2151 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002152 }
solenberg1ac56142015-10-13 03:58:19 -07002153
solenberg2100c0b2017-03-01 11:29:29 -08002154 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002155 {
2156 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002157 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002158 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002159 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002160 EXPECT_EQ(0u, info.receivers.size());
2161 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002162
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002163 // Deliver a new packet - a default receive stream should be created and we
2164 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002165 {
2166 cricket::VoiceMediaInfo info;
2167 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2168 SetAudioReceiveStreamStats();
2169 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002170 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002171 EXPECT_EQ(1u, info.receivers.size());
2172 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002173 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002174 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002175}
2176
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002177// Test that we can add and remove receive streams, and do proper send/playout.
2178// We can receive on multiple streams while sending one stream.
2179TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002180 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181
solenberg1ac56142015-10-13 03:58:19 -07002182 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002184 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
solenberg1ac56142015-10-13 03:58:19 -07002186 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002188 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002189 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002190
solenberg1ac56142015-10-13 03:58:19 -07002191 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002192 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
2194 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002195 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2196 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2197 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198
2199 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002200 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202
2203 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002204 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002205 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2206 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002207
aleloi84ef6152016-08-04 05:28:21 -07002208 // Restart playout and make sure recv streams are played out.
2209 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002210 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2211 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002212
aleloi84ef6152016-08-04 05:28:21 -07002213 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2215 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216}
2217
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002219// and start sending on it.
2220TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002221 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002222 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002223 EXPECT_CALL(apm_gc_,
2224 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002225 SetSendParameters(send_parameters_);
2226 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002228 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002230}
2231
wu@webrtc.org97077a32013-10-25 21:18:33 +00002232TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002233 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002234 EXPECT_CALL(adm_,
2235 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002236 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002237 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002238 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002239 send_parameters_.options.tx_agc_target_dbov = 3;
2240 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2241 send_parameters_.options.tx_agc_limiter = true;
2242 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002243 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2244 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2245 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002246 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002247
2248 // Check interaction with adjust_agc_delta. Both should be respected, for
2249 // backwards compatibility.
Oskar Sundbom78807582017-11-16 11:09:55 +01002250 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002251 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002252 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002253}
2254
minyue6b825df2016-10-31 04:08:32 -07002255TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2256 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002257 send_parameters_.options.audio_network_adaptor = true;
2258 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002259 SetSendParameters(send_parameters_);
2260 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002261 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002262}
2263
2264TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2265 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002266 send_parameters_.options.audio_network_adaptor = true;
2267 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002268 SetSendParameters(send_parameters_);
2269 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002270 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002271 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002272 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002273 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002274 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275}
2276
2277TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2278 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002279 send_parameters_.options.audio_network_adaptor = true;
2280 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002281 SetSendParameters(send_parameters_);
2282 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002283 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002284 const int initial_num = call_.GetNumCreatedSendStreams();
2285 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002286 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002287 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2288 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002289 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002290 // AudioSendStream not expected to be recreated.
2291 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2292 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002293 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002294}
2295
michaelt6672b262017-01-11 10:17:59 -08002296class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2297 : public WebRtcVoiceEngineTestFake {
2298 public:
2299 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2300 : WebRtcVoiceEngineTestFake(
2301 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2302 "Enabled/") {}
2303};
2304
2305TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2306 EXPECT_TRUE(SetupSendStream());
2307 cricket::AudioSendParameters parameters;
2308 parameters.codecs.push_back(kOpusCodec);
2309 SetSendParameters(parameters);
2310 const int initial_num = call_.GetNumCreatedSendStreams();
2311 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2312
2313 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2314 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002315 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2316 constexpr int kMinOverheadBps =
2317 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002318
2319 constexpr int kOpusMinBitrateBps = 6000;
2320 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002321 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002322 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002323 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002324 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002325
Oskar Sundbom78807582017-11-16 11:09:55 +01002326 parameters.options.audio_network_adaptor = true;
2327 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002328 SetSendParameters(parameters);
2329
ossu11bfc532017-02-16 05:37:06 -08002330 constexpr int kMinOverheadWithAnaBps =
2331 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002332
2333 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002335
minyuececec102017-03-27 13:04:25 -07002336 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002337 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002338}
2339
minyuececec102017-03-27 13:04:25 -07002340// This test is similar to
2341// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2342// additional field trial.
2343TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2344 SetRtpSendParameterUpdatesMaxBitrate) {
2345 EXPECT_TRUE(SetupSendStream());
2346 cricket::AudioSendParameters send_parameters;
2347 send_parameters.codecs.push_back(kOpusCodec);
2348 SetSendParameters(send_parameters);
2349
2350 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2351 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2352 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2353
2354 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002355 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002356 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2357
2358 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2359#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2360 constexpr int kMinOverhead = 3333;
2361#else
2362 constexpr int kMinOverhead = 6666;
2363#endif
2364 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2365}
2366
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002368// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002370 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002371 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002372}
2373
2374TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2375 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002376 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002377 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002378 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002379 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002380 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002381 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002382 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002383
solenberg85a04962015-10-27 03:35:21 -07002384 // Check stats for the added streams.
2385 {
2386 cricket::VoiceMediaInfo info;
2387 EXPECT_EQ(true, channel_->GetStats(&info));
2388
2389 // We have added one send stream. We should see the stats we've set.
2390 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002391 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002392 // We have added one receive stream. We should see empty stats.
2393 EXPECT_EQ(info.receivers.size(), 1u);
2394 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2395 }
solenberg1ac56142015-10-13 03:58:19 -07002396
solenberg566ef242015-11-06 15:34:49 -08002397 // Start sending - this affects some reported stats.
2398 {
2399 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002400 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002401 EXPECT_EQ(true, channel_->GetStats(&info));
2402 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002403 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002404 }
2405
solenberg2100c0b2017-03-01 11:29:29 -08002406 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002407 {
2408 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002409 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002410 EXPECT_EQ(true, channel_->GetStats(&info));
2411 EXPECT_EQ(1u, info.senders.size());
2412 EXPECT_EQ(0u, info.receivers.size());
2413 }
solenberg1ac56142015-10-13 03:58:19 -07002414
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002415 // Deliver a new packet - a default receive stream should be created and we
2416 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002417 {
2418 cricket::VoiceMediaInfo info;
2419 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2420 SetAudioReceiveStreamStats();
2421 EXPECT_EQ(true, channel_->GetStats(&info));
2422 EXPECT_EQ(1u, info.senders.size());
2423 EXPECT_EQ(1u, info.receivers.size());
2424 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002425 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002426 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002430// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002433 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2434 EXPECT_TRUE(AddRecvStream(kSsrcY));
2435 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002436}
2437
2438// Test that the local SSRC is the same on sending and receiving channels if the
2439// receive channel is created before the send channel.
2440TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002441 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002442 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002444 cricket::StreamParams::CreateLegacy(kSsrcX)));
2445 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2446 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447}
2448
2449// Test that we can properly receive packets.
2450TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002451 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002452 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002454
2455 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2456 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457}
2458
2459// Test that we can properly receive packets on multiple streams.
2460TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002461 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002462 const uint32_t ssrc1 = 1;
2463 const uint32_t ssrc2 = 2;
2464 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002465 EXPECT_TRUE(AddRecvStream(ssrc1));
2466 EXPECT_TRUE(AddRecvStream(ssrc2));
2467 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002468 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002469 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002470 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002472 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473 }
mflodman3d7db262016-04-29 00:57:13 -07002474
2475 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2476 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2477 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2478
2479 EXPECT_EQ(s1.received_packets(), 0);
2480 EXPECT_EQ(s2.received_packets(), 0);
2481 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002482
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002484 EXPECT_EQ(s1.received_packets(), 0);
2485 EXPECT_EQ(s2.received_packets(), 0);
2486 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002487
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002488 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002489 EXPECT_EQ(s1.received_packets(), 1);
2490 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2491 EXPECT_EQ(s2.received_packets(), 0);
2492 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002493
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002495 EXPECT_EQ(s1.received_packets(), 1);
2496 EXPECT_EQ(s2.received_packets(), 1);
2497 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2498 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002499
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002501 EXPECT_EQ(s1.received_packets(), 1);
2502 EXPECT_EQ(s2.received_packets(), 1);
2503 EXPECT_EQ(s3.received_packets(), 1);
2504 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002505
mflodman3d7db262016-04-29 00:57:13 -07002506 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2507 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2508 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509}
2510
solenberg2100c0b2017-03-01 11:29:29 -08002511// Test that receiving on an unsignaled stream works (a stream is created).
2512TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002513 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002514 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2515
solenberg7e63ef02015-11-20 00:19:43 -08002516 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002517
2518 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002519 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2520 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002521}
2522
solenberg2100c0b2017-03-01 11:29:29 -08002523// Test that receiving N unsignaled stream works (streams will be created), and
2524// that packets are forwarded to them all.
2525TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002526 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002527 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002528 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2529
solenberg2100c0b2017-03-01 11:29:29 -08002530 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002531 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002532 rtc::SetBE32(&packet[8], ssrc);
2533 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002534
solenberg2100c0b2017-03-01 11:29:29 -08002535 // Verify we have one new stream for each loop iteration.
2536 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002537 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2538 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002539 }
mflodman3d7db262016-04-29 00:57:13 -07002540
solenberg2100c0b2017-03-01 11:29:29 -08002541 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002542 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002543 rtc::SetBE32(&packet[8], ssrc);
2544 DeliverPacket(packet, sizeof(packet));
2545
solenbergebb349d2017-03-13 05:46:15 -07002546 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002547 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2548 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2549 }
2550
2551 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2552 constexpr uint32_t kAnotherSsrc = 667;
2553 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002554 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002555
2556 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002557 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002558 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002559 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002560 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2561 EXPECT_EQ(2, streams[i]->received_packets());
2562 }
2563 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2564 EXPECT_EQ(1, streams[i]->received_packets());
2565 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002566 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002567}
2568
solenberg2100c0b2017-03-01 11:29:29 -08002569// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002570// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002571TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002572 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002573 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002574 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2575
2576 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002577 const uint32_t signaled_ssrc = 1;
2578 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002579 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002580 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002581 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2582 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002583 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002584
2585 // Note that the first unknown SSRC cannot be 0, because we only support
2586 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002587 const uint32_t unsignaled_ssrc = 7011;
2588 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002589 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002590 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2591 packet, sizeof(packet)));
2592 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2593
2594 DeliverPacket(packet, sizeof(packet));
2595 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2596
2597 rtc::SetBE32(&packet[8], signaled_ssrc);
2598 DeliverPacket(packet, sizeof(packet));
2599 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2600 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002601}
2602
solenberg4904fb62017-02-17 12:01:14 -08002603// Two tests to verify that adding a receive stream with the same SSRC as a
2604// previously added unsignaled stream will only recreate underlying stream
2605// objects if the stream parameters have changed.
2606TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2607 EXPECT_TRUE(SetupChannel());
2608
2609 // Spawn unsignaled stream with SSRC=1.
2610 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2611 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2612 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2613 sizeof(kPcmuFrame)));
2614
2615 // Verify that the underlying stream object in Call is not recreated when a
2616 // stream with SSRC=1 is added.
2617 const auto& streams = call_.GetAudioReceiveStreams();
2618 EXPECT_EQ(1, streams.size());
2619 int audio_receive_stream_id = streams.front()->id();
2620 EXPECT_TRUE(AddRecvStream(1));
2621 EXPECT_EQ(1, streams.size());
2622 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2623}
2624
2625TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2626 EXPECT_TRUE(SetupChannel());
2627
2628 // Spawn unsignaled stream with SSRC=1.
2629 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2630 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2631 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2632 sizeof(kPcmuFrame)));
2633
2634 // Verify that the underlying stream object in Call *is* recreated when a
2635 // stream with SSRC=1 is added, and which has changed stream parameters.
2636 const auto& streams = call_.GetAudioReceiveStreams();
2637 EXPECT_EQ(1, streams.size());
2638 int audio_receive_stream_id = streams.front()->id();
2639 cricket::StreamParams stream_params;
2640 stream_params.ssrcs.push_back(1);
2641 stream_params.sync_label = "sync_label";
2642 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2643 EXPECT_EQ(1, streams.size());
2644 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2645}
2646
solenberg0a617e22015-10-20 15:49:38 -07002647// Test that we properly handle failures to add a receive stream.
2648TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002649 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002650 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002651 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652}
2653
solenberg0a617e22015-10-20 15:49:38 -07002654// Test that we properly handle failures to add a send stream.
2655TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002657 voe_.set_fail_create_channel(true);
2658 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2659}
2660
solenberg1ac56142015-10-13 03:58:19 -07002661// Test that AddRecvStream creates new stream.
2662TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002665 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002666 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667}
2668
2669// Test that after adding a recv stream, we do not decode more codecs than
2670// those previously passed into SetRecvCodecs.
2671TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002672 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002673 cricket::AudioRecvParameters parameters;
2674 parameters.codecs.push_back(kIsacCodec);
2675 parameters.codecs.push_back(kPcmuCodec);
2676 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002677 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002678 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2679 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2680 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002681}
2682
2683// Test that we properly clean up any streams that were added, even if
2684// not explicitly removed.
2685TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002686 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002687 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002688 EXPECT_TRUE(AddRecvStream(1));
2689 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2691 delete channel_;
2692 channel_ = NULL;
2693 EXPECT_EQ(0, voe_.GetNumChannels());
2694}
2695
wu@webrtc.org78187522013-10-07 23:32:02 +00002696TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002697 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002698 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002699}
2700
2701TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002703 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002704 // Manually delete channel to simulate a failure.
2705 int channel = voe_.GetLastChannel();
2706 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2707 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002708 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002709 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002710 EXPECT_NE(channel, new_channel);
2711 // The last created channel is deleted too.
2712 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002713}
2714
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002715// Test the InsertDtmf on default send stream as caller.
2716TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002717 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718}
2719
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002720// Test the InsertDtmf on default send stream as callee
2721TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002722 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002723}
2724
2725// Test the InsertDtmf on specified send stream as caller.
2726TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002727 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002728}
2729
2730// Test the InsertDtmf on specified send stream as callee.
2731TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002732 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733}
2734
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002735TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002736 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002737 EXPECT_CALL(adm_,
2738 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2739 EXPECT_CALL(adm_,
2740 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2741 EXPECT_CALL(adm_,
2742 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002743
solenberg246b8172015-12-08 09:50:23 -08002744 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2745 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746
solenberg246b8172015-12-08 09:50:23 -08002747 // Nothing set in AudioOptions, so everything should be as default.
2748 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002749 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002750 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002751 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2752 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753
2754 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759
2760 // Turn echo cancellation back on, with settings, and make sure
2761 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002762 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002764 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002765 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002767 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2768 // control.
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002771 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002772 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002773
2774 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002775 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002777 send_parameters_.options.delay_agnostic_aec = false;
2778 send_parameters_.options.extended_filter_aec = false;
2779 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002780 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002781
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002782 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002783 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2784 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002785 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002786 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002787
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002789 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002792 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002793 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002794 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002795 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796
2797 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002798 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2799 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2800 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002801 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002802 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002803 send_parameters_.options.auto_gain_control = true;
2804 send_parameters_.options.adjust_agc_delta = rtc::nullopt;
solenberg059fb442016-10-26 05:12:24 -07002805 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002806
2807 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002808 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002811 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002812 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002813 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002814 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2815 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2816 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002817 send_parameters_.options.noise_suppression = false;
2818 send_parameters_.options.highpass_filter = false;
2819 send_parameters_.options.typing_detection = false;
2820 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002821 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002822 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823
solenberg1ac56142015-10-13 03:58:19 -07002824 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002825 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002828 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002829 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002830 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002831 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2832 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2833 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002834 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002835}
2836
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002838 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002839 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002840 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002841 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002842 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002843 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002844 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002845 EXPECT_CALL(adm_,
2846 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2847 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2848 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002849 webrtc::AudioProcessing::Config apm_config;
2850 EXPECT_CALL(*apm_, GetConfig())
2851 .Times(10)
2852 .WillRepeatedly(ReturnPointee(&apm_config));
2853 EXPECT_CALL(*apm_, ApplyConfig(_))
2854 .Times(10)
2855 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002856 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002857
kwiberg686a8ef2016-02-26 03:00:35 -08002858 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002859 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002860 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002861 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002862 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002863 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864
2865 // Have to add a stream to make SetSend work.
2866 cricket::StreamParams stream1;
2867 stream1.ssrcs.push_back(1);
2868 channel1->AddSendStream(stream1);
2869 cricket::StreamParams stream2;
2870 stream2.ssrcs.push_back(2);
2871 channel2->AddSendStream(stream2);
2872
2873 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002874 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002875 parameters_options_all.options.echo_cancellation = true;
2876 parameters_options_all.options.auto_gain_control = true;
2877 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002878 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2879 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2880 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002881 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002882 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002883 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002884 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002885 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002886 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002887 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002888 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
2890 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002891 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002892 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002893 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002896 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002898 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002900 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002901 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002902 expected_options.echo_cancellation = true;
2903 expected_options.auto_gain_control = true;
2904 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002905 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906
2907 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002908 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002909 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002910 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2911 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002913 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002915 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002917 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002918 expected_options.echo_cancellation = true;
2919 expected_options.auto_gain_control = false;
2920 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002921 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922
solenberg76377c52017-02-21 00:54:31 -08002923 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002926 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002927 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002928 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002930 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002931
solenberg76377c52017-02-21 00:54:31 -08002932 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2933 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2934 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002935 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002936 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002937 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002938 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002939 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002940
solenberg76377c52017-02-21 00:54:31 -08002941 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2942 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2943 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002944 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002945 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002946 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002947 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002948 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002950 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002951 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2952 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002953 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2954 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002955 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2956 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2957 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002958 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002959 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002960 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002961 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002962 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002963 expected_options.echo_cancellation = true;
2964 expected_options.auto_gain_control = false;
2965 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002966 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967}
2968
wu@webrtc.orgde305012013-10-31 15:40:38 +00002969// This test verifies DSCP settings are properly applied on voice media channel.
2970TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002971 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002972 cricket::FakeNetworkInterface network_interface;
2973 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002974 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002975
peahb1c9d1d2017-07-25 15:45:24 -07002976 webrtc::AudioProcessing::Config apm_config;
2977 EXPECT_CALL(*apm_, GetConfig())
2978 .Times(3)
2979 .WillRepeatedly(ReturnPointee(&apm_config));
2980 EXPECT_CALL(*apm_, ApplyConfig(_))
2981 .Times(3)
2982 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002983 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002984
solenbergbc37fc82016-04-04 09:54:44 -07002985 channel.reset(
2986 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002987 channel->SetInterface(&network_interface);
2988 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2989 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2990
2991 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002992 channel.reset(
2993 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002994 channel->SetInterface(&network_interface);
2995 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2996
2997 // Verify that setting the option to false resets the
2998 // DiffServCodePoint.
2999 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003000 channel.reset(
3001 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003002 channel->SetInterface(&network_interface);
3003 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3004 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3005
3006 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003007}
3008
solenberg1ac56142015-10-13 03:58:19 -07003009TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003010 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011 cricket::WebRtcVoiceMediaChannel* media_channel =
3012 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003013 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003014 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003015 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3017 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3018 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003019 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003020 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021}
3022
solenberg1ac56142015-10-13 03:58:19 -07003023TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003024 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003026 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3027 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3028 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003029 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003030 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003031 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3032 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003033 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003034 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003035 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003036 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003037}
3038
solenberg4bac9c52015-10-09 02:32:53 -07003039TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003040 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003041 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003042 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003043 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003045 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3046 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3047 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003048}
3049
solenberg2100c0b2017-03-01 11:29:29 -08003050TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003051 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003052
3053 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003054 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003055 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3056
3057 // Should remember the volume "2" which will be set on new unsignaled streams,
3058 // and also set the gain to 2 on existing unsignaled streams.
3059 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3060 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3061
3062 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3063 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3064 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3065 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3066 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3067 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3068
3069 // Setting gain with SSRC=0 should affect all unsignaled streams.
3070 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003071 if (kMaxUnsignaledRecvStreams > 1) {
3072 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3073 }
solenberg2100c0b2017-03-01 11:29:29 -08003074 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3075
3076 // Setting gain on an individual stream affects only that.
3077 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003078 if (kMaxUnsignaledRecvStreams > 1) {
3079 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3080 }
solenberg2100c0b2017-03-01 11:29:29 -08003081 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082}
3083
pbos8fc7fa72015-07-15 08:02:58 -07003084TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003085 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003086 const std::string kSyncLabel = "AvSyncLabel";
3087
solenbergff976312016-03-30 23:28:51 -07003088 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003089 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3090 sp.sync_label = kSyncLabel;
3091 // Creating two channels to make sure that sync label is set properly for both
3092 // the default voice channel and following ones.
3093 EXPECT_TRUE(channel_->AddRecvStream(sp));
3094 sp.ssrcs[0] += 1;
3095 EXPECT_TRUE(channel_->AddRecvStream(sp));
3096
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003097 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003098 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003099 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003100 << "SyncGroup should be set based on sync_label";
3101 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003102 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003103 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003104}
3105
solenberg3a941542015-11-16 07:34:50 -08003106// TODO(solenberg): Remove, once recv streams are configured through Call.
3107// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003108TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109 // Test that setting the header extensions results in the expected state
3110 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003111 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 ssrcs.push_back(223);
3113 ssrcs.push_back(224);
3114
solenbergff976312016-03-30 23:28:51 -07003115 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003116 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003117 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003118 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119 cricket::StreamParams::CreateLegacy(ssrc)));
3120 }
3121
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003122 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003123 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003124 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 EXPECT_NE(nullptr, s);
3126 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3127 }
3128
3129 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003130 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003131 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003132 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003133 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003134 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003135 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003136 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003137 EXPECT_NE(nullptr, s);
3138 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003139 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3140 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003141 for (const auto& s_ext : s_exts) {
3142 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003143 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003144 }
3145 }
3146 }
3147 }
3148
3149 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003150 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003151 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003152 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003153 EXPECT_NE(nullptr, s);
3154 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3155 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003156}
3157
3158TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3159 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003160 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003161 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003162 static const unsigned char kRtcp[] = {
3163 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3164 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3167 };
jbaucheec21bd2016-03-20 06:15:43 -07003168 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003169
solenbergff976312016-03-30 23:28:51 -07003170 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003171 cricket::WebRtcVoiceMediaChannel* media_channel =
3172 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003173 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003174 EXPECT_TRUE(media_channel->AddRecvStream(
3175 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3176
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003177 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003178 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003179 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003180 EXPECT_EQ(0, s->received_packets());
3181 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3182 EXPECT_EQ(1, s->received_packets());
3183 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3184 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003185}
Minyue2013aec2015-05-13 14:14:42 +02003186
solenberg0a617e22015-10-20 15:49:38 -07003187// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003188// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003189TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003191 EXPECT_TRUE(AddRecvStream(kSsrcY));
3192 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003193 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003194 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3195 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3196 EXPECT_TRUE(AddRecvStream(kSsrcW));
3197 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003198}
3199
solenberg7602aab2016-11-14 11:30:07 -08003200TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3201 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003202 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003203 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003204 cricket::StreamParams::CreateLegacy(kSsrcY)));
3205 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3206 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3207 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003208 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003209 cricket::StreamParams::CreateLegacy(kSsrcW)));
3210 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3211 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003212}
stefan658910c2015-09-03 05:48:32 -07003213
deadbeef884f5852016-01-15 09:20:04 -08003214TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003215 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003216 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3217 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003218
3219 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003220 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3221 EXPECT_TRUE(AddRecvStream(kSsrcX));
3222 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003223
3224 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003225 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3226 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003227
3228 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003229 channel_->SetRawAudioSink(kSsrcX, nullptr);
3230 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003231}
3232
solenberg2100c0b2017-03-01 11:29:29 -08003233TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003234 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003235 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3236 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003237 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3238 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003239
3240 // Should be able to set a default sink even when no stream exists.
3241 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3242
solenberg2100c0b2017-03-01 11:29:29 -08003243 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3244 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003245 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003246 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003247
3248 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003249 channel_->SetRawAudioSink(kSsrc0, nullptr);
3250 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003251
3252 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003253 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3254 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003255
3256 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003257 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003258 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3260
3261 // Spawn another unsignaled stream - it should be assigned the default sink
3262 // and the previous unsignaled stream should lose it.
3263 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3264 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3265 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3266 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003267 if (kMaxUnsignaledRecvStreams > 1) {
3268 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3269 }
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3271
3272 // Reset the default sink - the second unsignaled stream should lose it.
3273 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003274 if (kMaxUnsignaledRecvStreams > 1) {
3275 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3276 }
solenberg2100c0b2017-03-01 11:29:29 -08003277 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3278
3279 // Try setting the default sink while two streams exists.
3280 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003281 if (kMaxUnsignaledRecvStreams > 1) {
3282 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3283 }
solenberg2100c0b2017-03-01 11:29:29 -08003284 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3285
3286 // Try setting the sink for the first unsignaled stream using its known SSRC.
3287 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003288 if (kMaxUnsignaledRecvStreams > 1) {
3289 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3290 }
solenberg2100c0b2017-03-01 11:29:29 -08003291 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003292 if (kMaxUnsignaledRecvStreams > 1) {
3293 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3294 }
deadbeef884f5852016-01-15 09:20:04 -08003295}
3296
skvlad7a43d252016-03-22 15:32:27 -07003297// Test that, just like the video channel, the voice channel communicates the
3298// network state to the call.
3299TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003300 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003301
3302 EXPECT_EQ(webrtc::kNetworkUp,
3303 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3304 EXPECT_EQ(webrtc::kNetworkUp,
3305 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3306
3307 channel_->OnReadyToSend(false);
3308 EXPECT_EQ(webrtc::kNetworkDown,
3309 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3310 EXPECT_EQ(webrtc::kNetworkUp,
3311 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3312
3313 channel_->OnReadyToSend(true);
3314 EXPECT_EQ(webrtc::kNetworkUp,
3315 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3316 EXPECT_EQ(webrtc::kNetworkUp,
3317 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3318}
3319
aleloi18e0b672016-10-04 02:45:47 -07003320// Test that playout is still started after changing parameters
3321TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3322 SetupRecvStream();
3323 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003324 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003325
3326 // Changing RTP header extensions will recreate the AudioReceiveStream.
3327 cricket::AudioRecvParameters parameters;
3328 parameters.extensions.push_back(
3329 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3330 channel_->SetRecvParameters(parameters);
3331
solenberg2100c0b2017-03-01 11:29:29 -08003332 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003333}
3334
stefan658910c2015-09-03 05:48:32 -07003335// Tests that the library initializes and shuts down properly.
3336TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003337 // If the VoiceEngine wants to gather available codecs early, that's fine but
3338 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003339 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003340 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3341 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003342 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003343 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003344 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003345 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003346 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003347 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003348 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003349 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3350 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003351 EXPECT_TRUE(channel != nullptr);
3352 delete channel;
solenbergff976312016-03-30 23:28:51 -07003353}
stefan658910c2015-09-03 05:48:32 -07003354
solenbergff976312016-03-30 23:28:51 -07003355// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003356TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3357 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003358 EXPECT_CALL(adm, AddRef()).Times(3);
3359 EXPECT_CALL(adm, Release())
3360 .Times(3)
3361 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003362 {
peaha9cc40b2017-06-29 08:32:09 -07003363 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3364 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003365 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003366 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003367 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003368 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003369 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003370 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003371 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003372 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3373 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3374 EXPECT_TRUE(channel != nullptr);
3375 delete channel;
3376 }
stefan658910c2015-09-03 05:48:32 -07003377}
3378
ossu20a4b3f2017-04-27 02:08:52 -07003379// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3380TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003381 // TODO(ossu): Why are the payload types of codecs with non-static payload
3382 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003383 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003384 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3385 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003386 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003387 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003388 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003389 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003390 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003391 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3392 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3393 (clockrate == 0 || codec.clockrate == clockrate);
3394 };
3395 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003396 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003397 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003399 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003400 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003401 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003402 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003403 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003404 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003405 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003406 EXPECT_EQ(126, codec.id);
3407 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3408 // Remove these checks once both send and receive side assigns payload types
3409 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003410 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003411 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003412 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003413 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003414 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003415 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003416 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003417 EXPECT_EQ(111, codec.id);
3418 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3419 EXPECT_EQ("10", codec.params.find("minptime")->second);
3420 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3421 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003422 }
3423 }
stefan658910c2015-09-03 05:48:32 -07003424}
3425
3426// Tests that VoE supports at least 32 channels
3427TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003428 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003429 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3430 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003431 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003432 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003433 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003434 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003435 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003436 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003437 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003438
3439 cricket::VoiceMediaChannel* channels[32];
3440 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003441 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003442 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3443 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003444 if (!channel)
3445 break;
stefan658910c2015-09-03 05:48:32 -07003446 channels[num_channels++] = channel;
3447 }
3448
tfarina5237aaf2015-11-10 23:44:30 -08003449 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003450 EXPECT_EQ(expected, num_channels);
3451
3452 while (num_channels > 0) {
3453 delete channels[--num_channels];
3454 }
stefan658910c2015-09-03 05:48:32 -07003455}
3456
3457// Test that we set our preferred codecs properly.
3458TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003459 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3460 // - Check that our builtin codecs are usable by Channel.
3461 // - The codecs provided by the engine is usable by Channel.
3462 // It does not check that the codecs in the RecvParameters are actually
3463 // what we sent in - though it's probably reasonable to expect so, if
3464 // SetRecvParameters returns true.
3465 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003466 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003467 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3468 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003469 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003470 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003471 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003472 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003473 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003474 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003475 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003476 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3477 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003478 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003479 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003480 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003481}
ossu9def8002017-02-09 05:14:32 -08003482
3483TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3484 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003485 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3486 {48000, 2, 16000, 10000, 20000}};
3487 spec1.info.allow_comfort_noise = false;
3488 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003489 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003490 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3491 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003492 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003493 specs.push_back(webrtc::AudioCodecSpec{
3494 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3495 {16000, 1, 13300}});
3496 specs.push_back(
3497 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3498 specs.push_back(
3499 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003500
ossueb1fde42017-05-02 06:46:30 -07003501 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3502 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3503 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003504 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003505 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003506 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003507 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003508
peaha9cc40b2017-06-29 08:32:09 -07003509 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3510 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003511 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003512 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003513 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003514 auto codecs = engine.recv_codecs();
3515 EXPECT_EQ(11, codecs.size());
3516
3517 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3518 // check the actual values safely, to provide better test results.
3519 auto get_codec =
3520 [&codecs](size_t index) -> const cricket::AudioCodec& {
3521 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3522 if (codecs.size() > index)
3523 return codecs[index];
3524 return missing_codec;
3525 };
3526
3527 // Ensure the general codecs are generated first and in order.
3528 for (size_t i = 0; i != specs.size(); ++i) {
3529 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3530 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3531 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3532 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3533 }
3534
3535 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003536 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003537 auto find_codec =
3538 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3539 for (size_t i = 0; i != codecs.size(); ++i) {
3540 const cricket::AudioCodec& codec = codecs[i];
3541 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3542 codec.clockrate == format.clockrate_hz &&
3543 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003544 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003545 }
3546 }
3547 return -1;
3548 };
3549
3550 // Ensure all supplementary codecs are generated last. Their internal ordering
3551 // is not important.
3552 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3553 const int num_specs = static_cast<int>(specs.size());
3554 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3555 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3556 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3557 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3558 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3559 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3560 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3561}