blob: dbee6d318a2582424783f635e99ea1847e462111 [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>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070014#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080015#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000016#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080017#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080018#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070019#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080020#include "webrtc/media/base/fakemediaengine.h"
21#include "webrtc/media/base/fakenetworkinterface.h"
22#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080023#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010024#include "webrtc/media/engine/fakewebrtccall.h"
25#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
26#include "webrtc/media/engine/webrtcvoiceengine.h"
solenbergbc37fc82016-04-04 09:54:44 -070027#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070028#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080029#include "webrtc/pc/channel.h"
30#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080031#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070032#include "webrtc/test/mock_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070033#include "webrtc/test/mock_audio_encoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080034#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
kwiberg1c07c702017-03-27 07:15:49 -070036using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070037using testing::Return;
38using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000039
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020040namespace {
41
solenberg418b7d32017-06-13 00:38:27 -070042constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070043
deadbeef67cf2c12016-04-13 10:07:16 -070044const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
45const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070046const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070047const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
48const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
50const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080051const cricket::AudioCodec
52 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
53const cricket::AudioCodec
54 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
55
solenberg2100c0b2017-03-01 11:29:29 -080056const uint32_t kSsrc0 = 0;
57const uint32_t kSsrc1 = 1;
58const uint32_t kSsrcX = 0x99;
59const uint32_t kSsrcY = 0x17;
60const uint32_t kSsrcZ = 0x42;
61const uint32_t kSsrcW = 0x02;
62const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063
solenberg971cab02016-06-14 10:02:41 -070064constexpr int kRtpHistoryMs = 5000;
65
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066class FakeVoEWrapper : public cricket::VoEWrapper {
67 public:
68 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070069 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070 }
71};
skvlad11a9cbf2016-10-07 11:53:05 -070072
solenberg76377c52017-02-21 00:54:31 -080073class MockTransmitMixer : public webrtc::voe::TransmitMixer {
74 public:
75 MockTransmitMixer() = default;
76 virtual ~MockTransmitMixer() = default;
77
78 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
79};
solenberg9a5f032222017-03-15 06:14:12 -070080
81void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
82 RTC_DCHECK(adm);
83 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
84 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
85#if !defined(WEBRTC_IOS)
86 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
87 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
88 ChannelType::kChannelBoth)).WillOnce(Return(0));
89#if defined(WEBRTC_WIN)
90 EXPECT_CALL(*adm, SetRecordingDevice(
91 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
92 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
93 .WillOnce(Return(0));
94#else
95 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
96#endif // #if defined(WEBRTC_WIN)
97 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
98 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
99 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
100 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
101#if defined(WEBRTC_WIN)
102 EXPECT_CALL(*adm, SetPlayoutDevice(
103 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
104 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
105 .WillOnce(Return(0));
106#else
107 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
108#endif // #if defined(WEBRTC_WIN)
109 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
110 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
111 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
112#endif // #if !defined(WEBRTC_IOS)
113 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
116 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
117}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200118} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119
solenbergff976312016-03-30 23:28:51 -0700120// Tests that our stub library "works".
121TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700122 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700123 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700124 StrictMock<webrtc::test::MockAudioProcessing> apm;
125 EXPECT_CALL(apm, ApplyConfig(testing::_));
126 EXPECT_CALL(apm, SetExtraOptions(testing::_));
127 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
aleloi048cbdd2017-05-29 02:56:27 -0700128 EXPECT_CALL(apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800129 StrictMock<MockTransmitMixer> transmit_mixer;
130 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
131 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700132 EXPECT_FALSE(voe.IsInited());
133 {
ossuc54071d2016-08-17 02:45:41 -0700134 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700135 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
136 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700137 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700138 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700139 EXPECT_TRUE(voe.IsInited());
140 }
141 EXPECT_FALSE(voe.IsInited());
142}
143
deadbeef884f5852016-01-15 09:20:04 -0800144class FakeAudioSink : public webrtc::AudioSinkInterface {
145 public:
146 void OnData(const Data& audio) override {}
147};
148
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800149class FakeAudioSource : public cricket::AudioSource {
150 void SetSink(Sink* sink) override {}
151};
152
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153class WebRtcVoiceEngineTestFake : public testing::Test {
154 public:
stefanba4c0e42016-02-04 04:12:24 -0800155 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
156
157 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800158 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
159 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
160 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700161 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800162 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700163 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800164 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700165 EXPECT_CALL(apm_, ApplyConfig(testing::_));
166 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
167 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
aleloi048cbdd2017-05-29 02:56:27 -0700168 EXPECT_CALL(apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800169 // Default Options.
170 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
171 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
172 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
173 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
174 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
175 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
176 // Init does not overwrite default AGC config.
177 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
178 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
179 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
180 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
181 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
182 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700183 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800184 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700185 // factories. Those tests should probably be moved elsewhere.
186 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
187 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
188 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
189 decoder_factory, nullptr,
190 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700191 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200192 send_parameters_.codecs.push_back(kPcmuCodec);
193 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800194 // Default Options.
195 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196 }
solenberg8189b022016-06-14 12:13:00 -0700197
solenbergff976312016-03-30 23:28:51 -0700198 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700199 EXPECT_CALL(apm_, ApplyConfig(testing::_));
200 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700201 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
202 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200203 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000204 }
solenberg8189b022016-06-14 12:13:00 -0700205
solenbergff976312016-03-30 23:28:51 -0700206 bool SetupRecvStream() {
207 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700208 return false;
209 }
solenberg2100c0b2017-03-01 11:29:29 -0800210 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700211 }
solenberg8189b022016-06-14 12:13:00 -0700212
solenbergff976312016-03-30 23:28:51 -0700213 bool SetupSendStream() {
214 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000215 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 }
solenberg2100c0b2017-03-01 11:29:29 -0800217 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800218 return false;
219 }
solenberg059fb442016-10-26 05:12:24 -0700220 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800221 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 }
solenberg8189b022016-06-14 12:13:00 -0700223
224 bool AddRecvStream(uint32_t ssrc) {
225 EXPECT_TRUE(channel_);
226 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
227 }
228
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000229 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700230 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700231 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800232 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
233 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700234 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800235 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000236 }
solenberg8189b022016-06-14 12:13:00 -0700237
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700239 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000240 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 }
solenberg8189b022016-06-14 12:13:00 -0700242
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200243 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000245 }
246
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100247 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
248 const auto* send_stream = call_.GetAudioSendStream(ssrc);
249 EXPECT_TRUE(send_stream);
250 return *send_stream;
251 }
252
deadbeef884f5852016-01-15 09:20:04 -0800253 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
254 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
255 EXPECT_TRUE(recv_stream);
256 return *recv_stream;
257 }
258
solenberg3a941542015-11-16 07:34:50 -0800259 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800260 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800261 }
262
solenberg7add0582015-11-20 09:59:34 -0800263 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800264 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800265 }
266
solenberg059fb442016-10-26 05:12:24 -0700267 void SetSend(bool enable) {
268 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700269 if (enable) {
270 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
271 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
272 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700273 EXPECT_CALL(apm_, ApplyConfig(testing::_));
274 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700275 }
solenberg059fb442016-10-26 05:12:24 -0700276 channel_->SetSend(enable);
277 }
278
279 void SetSendParameters(const cricket::AudioSendParameters& params) {
280 EXPECT_CALL(apm_, ApplyConfig(testing::_));
281 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
282 ASSERT_TRUE(channel_);
283 EXPECT_TRUE(channel_->SetSendParameters(params));
284 }
285
minyue6b825df2016-10-31 04:08:32 -0700286 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
287 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700288 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
289 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700290 if (enable && options) {
291 EXPECT_CALL(apm_, ApplyConfig(testing::_));
292 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
293 }
294 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700295 }
296
solenbergffbbcac2016-11-17 05:25:37 -0800297 void TestInsertDtmf(uint32_t ssrc, bool caller,
298 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700299 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000300 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700301 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000302 // send stream.
303 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800304 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000305 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700308 SetSendParameters(send_parameters_);
309 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800311 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800312 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700313 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315
316 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700317 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800318 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000319 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800320 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321 }
322
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800324 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100326 // Test send.
327 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800328 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100329 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800330 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800331 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800332 EXPECT_EQ(codec.id, telephone_event.payload_type);
333 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100334 EXPECT_EQ(2, telephone_event.event_code);
335 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 }
337
338 // Test that send bandwidth is set correctly.
339 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000340 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
341 // |expected_result| is the expected result from SetMaxSendBandwidth().
342 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700343 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
344 int max_bitrate,
345 bool expected_result,
346 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200347 cricket::AudioSendParameters parameters;
348 parameters.codecs.push_back(codec);
349 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700350 if (expected_result) {
351 SetSendParameters(parameters);
352 } else {
353 EXPECT_FALSE(channel_->SetSendParameters(parameters));
354 }
solenberg2100c0b2017-03-01 11:29:29 -0800355 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 }
357
skvlade0d46372016-04-07 22:59:22 -0700358 // Sets the per-stream maximum bitrate limit for the specified SSRC.
359 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700360 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700361 EXPECT_EQ(1UL, parameters.encodings.size());
362
deadbeefe702b302017-02-04 12:09:01 -0800363 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700364 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700365 }
366
solenberg059fb442016-10-26 05:12:24 -0700367 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700368 cricket::AudioSendParameters send_parameters;
369 send_parameters.codecs.push_back(codec);
370 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700371 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700372 }
373
ossu20a4b3f2017-04-27 02:08:52 -0700374 void CheckSendCodecBitrate(int32_t ssrc,
375 const char expected_name[],
376 int expected_bitrate) {
377 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
378 EXPECT_EQ(expected_name, spec->format.name);
379 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700380 }
381
ossu20a4b3f2017-04-27 02:08:52 -0700382 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
383 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700384 }
385
minyue6b825df2016-10-31 04:08:32 -0700386 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
387 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
388 }
389
skvlade0d46372016-04-07 22:59:22 -0700390 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
391 int global_max,
392 int stream_max,
393 bool expected_result,
394 int expected_codec_bitrate) {
395 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800396 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700397
398 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700399 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800400 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700401
402 // Verify that reading back the parameters gives results
403 // consistent with the Set() result.
404 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800405 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700406 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
407 EXPECT_EQ(expected_result ? stream_max : -1,
408 resulting_parameters.encodings[0].max_bitrate_bps);
409
410 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800411 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700412 }
413
stefan13f1a0a2016-11-30 07:22:58 -0800414 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
415 int expected_min_bitrate_bps,
416 const char* start_bitrate_kbps,
417 int expected_start_bitrate_bps,
418 const char* max_bitrate_kbps,
419 int expected_max_bitrate_bps) {
420 EXPECT_TRUE(SetupSendStream());
421 auto& codecs = send_parameters_.codecs;
422 codecs.clear();
423 codecs.push_back(kOpusCodec);
424 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
425 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
426 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
427 SetSendParameters(send_parameters_);
428
429 EXPECT_EQ(expected_min_bitrate_bps,
430 call_.GetConfig().bitrate_config.min_bitrate_bps);
431 EXPECT_EQ(expected_start_bitrate_bps,
432 call_.GetConfig().bitrate_config.start_bitrate_bps);
433 EXPECT_EQ(expected_max_bitrate_bps,
434 call_.GetConfig().bitrate_config.max_bitrate_bps);
435 }
436
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000437 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700438 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000439
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000440 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800441 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000442
443 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700444 send_parameters_.extensions.push_back(
445 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700446 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800447 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200450 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700451 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800452 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000453
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000454 // Ensure extension is set properly.
455 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700456 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700457 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800458 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
459 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
460 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000461
solenberg7add0582015-11-20 09:59:34 -0800462 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800464 cricket::StreamParams::CreateLegacy(kSsrcY)));
465 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
466 call_.GetAudioSendStream(kSsrcY));
467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000470
471 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200472 send_parameters_.codecs.push_back(kPcmuCodec);
473 send_parameters_.extensions.clear();
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());
476 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000477 }
478
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000479 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700480 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000481
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000484
485 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700486 recv_parameters_.extensions.push_back(
487 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800488 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800489 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000491 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800492 recv_parameters_.extensions.clear();
493 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800494 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000495
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000496 // Ensure extension is set properly.
497 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700498 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800499 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800500 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
501 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
502 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000503
solenberg7add0582015-11-20 09:59:34 -0800504 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800505 EXPECT_TRUE(AddRecvStream(kSsrcY));
506 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
507 call_.GetAudioReceiveStream(kSsrcY));
508 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
509 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
510 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000511
512 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800513 recv_parameters_.extensions.clear();
514 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
516 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000517 }
518
solenberg85a04962015-10-27 03:35:21 -0700519 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
520 webrtc::AudioSendStream::Stats stats;
521 stats.local_ssrc = 12;
522 stats.bytes_sent = 345;
523 stats.packets_sent = 678;
524 stats.packets_lost = 9012;
525 stats.fraction_lost = 34.56f;
526 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800527 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700528 stats.ext_seqnum = 789;
529 stats.jitter_ms = 12;
530 stats.rtt_ms = 345;
531 stats.audio_level = 678;
532 stats.aec_quality_min = 9.01f;
533 stats.echo_delay_median_ms = 234;
534 stats.echo_delay_std_ms = 567;
535 stats.echo_return_loss = 890;
536 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700537 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800538 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700539 stats.typing_noise_detected = true;
540 return stats;
541 }
542 void SetAudioSendStreamStats() {
543 for (auto* s : call_.GetAudioSendStreams()) {
544 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200545 }
solenberg85a04962015-10-27 03:35:21 -0700546 }
solenberg566ef242015-11-06 15:34:49 -0800547 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
548 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700549 const auto stats = GetAudioSendStreamStats();
550 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
551 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
552 EXPECT_EQ(info.packets_sent, stats.packets_sent);
553 EXPECT_EQ(info.packets_lost, stats.packets_lost);
554 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
555 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800556 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700557 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
558 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
559 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
560 EXPECT_EQ(info.audio_level, stats.audio_level);
561 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
562 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
563 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
564 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
565 EXPECT_EQ(info.echo_return_loss_enhancement,
566 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700567 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800568 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
569 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800570 EXPECT_EQ(info.typing_noise_detected,
571 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700572 }
573
574 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
575 webrtc::AudioReceiveStream::Stats stats;
576 stats.remote_ssrc = 123;
577 stats.bytes_rcvd = 456;
578 stats.packets_rcvd = 768;
579 stats.packets_lost = 101;
580 stats.fraction_lost = 23.45f;
581 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800582 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700583 stats.ext_seqnum = 678;
584 stats.jitter_ms = 901;
585 stats.jitter_buffer_ms = 234;
586 stats.jitter_buffer_preferred_ms = 567;
587 stats.delay_estimate_ms = 890;
588 stats.audio_level = 1234;
589 stats.expand_rate = 5.67f;
590 stats.speech_expand_rate = 8.90f;
591 stats.secondary_decoded_rate = 1.23f;
592 stats.accelerate_rate = 4.56f;
593 stats.preemptive_expand_rate = 7.89f;
594 stats.decoding_calls_to_silence_generator = 12;
595 stats.decoding_calls_to_neteq = 345;
596 stats.decoding_normal = 67890;
597 stats.decoding_plc = 1234;
598 stats.decoding_cng = 5678;
599 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700600 stats.decoding_muted_output = 3456;
601 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200602 return stats;
603 }
604 void SetAudioReceiveStreamStats() {
605 for (auto* s : call_.GetAudioReceiveStreams()) {
606 s->SetStats(GetAudioReceiveStreamStats());
607 }
608 }
609 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700610 const auto stats = GetAudioReceiveStreamStats();
611 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
612 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
613 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
614 EXPECT_EQ(info.packets_lost, stats.packets_lost);
615 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
616 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800617 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700618 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
619 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
620 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200621 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700622 stats.jitter_buffer_preferred_ms);
623 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
624 EXPECT_EQ(info.audio_level, stats.audio_level);
625 EXPECT_EQ(info.expand_rate, stats.expand_rate);
626 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
627 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
628 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
629 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200630 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700631 stats.decoding_calls_to_silence_generator);
632 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
633 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
634 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
635 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
636 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700637 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700638 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 }
hbos1acfbd22016-11-17 23:43:29 -0800640 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
641 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
642 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
643 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
644 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
645 codec.ToCodecParameters());
646 }
647 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
648 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
649 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
650 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
651 codec.ToCodecParameters());
652 }
653 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200654
peah8271d042016-11-22 07:24:52 -0800655 bool IsHighPassFilterEnabled() {
656 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
657 }
658
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000659 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700660 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700661 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800662 webrtc::test::MockGainControl& apm_gc_;
663 webrtc::test::MockEchoCancellation& apm_ec_;
664 webrtc::test::MockNoiseSuppression& apm_ns_;
665 webrtc::test::MockVoiceDetection& apm_vd_;
666 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700667 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200668 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700670 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700671 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200672 cricket::AudioSendParameters send_parameters_;
673 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800674 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800675 private:
676 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000677};
678
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679// Tests that we can create and destroy a channel.
680TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700681 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000682}
683
solenberg31fec402016-05-06 02:13:12 -0700684// Test that we can add a send stream and that it has the correct defaults.
685TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
686 EXPECT_TRUE(SetupChannel());
687 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800688 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
689 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
690 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700691 EXPECT_EQ("", config.rtp.c_name);
692 EXPECT_EQ(0u, config.rtp.extensions.size());
693 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
694 config.send_transport);
695}
696
697// Test that we can add a receive stream and that it has the correct defaults.
698TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
699 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800700 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700701 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800702 GetRecvStreamConfig(kSsrcX);
703 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700704 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
705 EXPECT_FALSE(config.rtp.transport_cc);
706 EXPECT_EQ(0u, config.rtp.extensions.size());
707 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
708 config.rtcp_send_transport);
709 EXPECT_EQ("", config.sync_group);
710}
711
stefanba4c0e42016-02-04 04:12:24 -0800712TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700713 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800714 bool opus_found = false;
715 for (cricket::AudioCodec codec : codecs) {
716 if (codec.name == "opus") {
717 EXPECT_TRUE(HasTransportCc(codec));
718 opus_found = true;
719 }
720 }
721 EXPECT_TRUE(opus_found);
722}
723
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724// Test that we set our inbound codecs properly, including changing PT.
725TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700726 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200727 cricket::AudioRecvParameters parameters;
728 parameters.codecs.push_back(kIsacCodec);
729 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800730 parameters.codecs.push_back(kTelephoneEventCodec1);
731 parameters.codecs.push_back(kTelephoneEventCodec2);
732 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200733 parameters.codecs[2].id = 126;
734 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800735 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700736 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
737 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
738 {{0, {"PCMU", 8000, 1}},
739 {106, {"ISAC", 16000, 1}},
740 {126, {"telephone-event", 8000, 1}},
741 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742}
743
744// Test that we fail to set an unknown inbound codec.
745TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700746 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200747 cricket::AudioRecvParameters parameters;
748 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700749 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200750 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751}
752
753// Test that we fail if we have duplicate types in the inbound list.
754TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700755 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200756 cricket::AudioRecvParameters parameters;
757 parameters.codecs.push_back(kIsacCodec);
758 parameters.codecs.push_back(kCn16000Codec);
759 parameters.codecs[1].id = kIsacCodec.id;
760 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761}
762
763// Test that we can decode OPUS without stereo parameters.
764TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700765 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200766 cricket::AudioRecvParameters parameters;
767 parameters.codecs.push_back(kIsacCodec);
768 parameters.codecs.push_back(kPcmuCodec);
769 parameters.codecs.push_back(kOpusCodec);
770 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800771 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700772 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
773 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
774 {{0, {"PCMU", 8000, 1}},
775 {103, {"ISAC", 16000, 1}},
776 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777}
778
779// Test that we can decode OPUS with stereo = 0.
780TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700781 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200782 cricket::AudioRecvParameters parameters;
783 parameters.codecs.push_back(kIsacCodec);
784 parameters.codecs.push_back(kPcmuCodec);
785 parameters.codecs.push_back(kOpusCodec);
786 parameters.codecs[2].params["stereo"] = "0";
787 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800788 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700789 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
790 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
791 {{0, {"PCMU", 8000, 1}},
792 {103, {"ISAC", 16000, 1}},
793 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794}
795
796// Test that we can decode OPUS with stereo = 1.
797TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700798 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200799 cricket::AudioRecvParameters parameters;
800 parameters.codecs.push_back(kIsacCodec);
801 parameters.codecs.push_back(kPcmuCodec);
802 parameters.codecs.push_back(kOpusCodec);
803 parameters.codecs[2].params["stereo"] = "1";
804 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800805 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700806 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
807 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
808 {{0, {"PCMU", 8000, 1}},
809 {103, {"ISAC", 16000, 1}},
810 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811}
812
813// Test that changes to recv codecs are applied to all streams.
814TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700815 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200816 cricket::AudioRecvParameters parameters;
817 parameters.codecs.push_back(kIsacCodec);
818 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800819 parameters.codecs.push_back(kTelephoneEventCodec1);
820 parameters.codecs.push_back(kTelephoneEventCodec2);
821 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200822 parameters.codecs[2].id = 126;
823 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700824 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
825 EXPECT_TRUE(AddRecvStream(ssrc));
826 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
827 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
828 {{0, {"PCMU", 8000, 1}},
829 {106, {"ISAC", 16000, 1}},
830 {126, {"telephone-event", 8000, 1}},
831 {107, {"telephone-event", 32000, 1}}})));
832 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000833}
834
835TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700836 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200837 cricket::AudioRecvParameters parameters;
838 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800839 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841
solenberg2100c0b2017-03-01 11:29:29 -0800842 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800843 ASSERT_EQ(1, dm.count(106));
844 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847// Test that we can apply the same set of codecs again while playing.
848TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700849 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200850 cricket::AudioRecvParameters parameters;
851 parameters.codecs.push_back(kIsacCodec);
852 parameters.codecs.push_back(kCn16000Codec);
853 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700854 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856
deadbeefcb383672017-04-26 16:28:42 -0700857 // Remapping a payload type to a different codec should fail.
858 parameters.codecs[0] = kOpusCodec;
859 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200860 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800861 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862}
863
864// Test that we can add a codec while playing.
865TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700866 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200867 cricket::AudioRecvParameters parameters;
868 parameters.codecs.push_back(kIsacCodec);
869 parameters.codecs.push_back(kCn16000Codec);
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700871 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200873 parameters.codecs.push_back(kOpusCodec);
874 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800875 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876}
877
deadbeefcb383672017-04-26 16:28:42 -0700878// Test that we accept adding the same codec with a different payload type.
879// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
880TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
881 EXPECT_TRUE(SetupRecvStream());
882 cricket::AudioRecvParameters parameters;
883 parameters.codecs.push_back(kIsacCodec);
884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
885
886 ++parameters.codecs[0].id;
887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
888}
889
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700891 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000893 // Test that when autobw is enabled, bitrate is kept as the default
894 // value. autobw is enabled for the following tests because the target
895 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896
897 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700898 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
900 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700901 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902
ossu20a4b3f2017-04-27 02:08:52 -0700903 // opus, default bitrate == 32000 in mono.
904 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905}
906
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000907TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700908 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700911 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
912 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700913 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700916 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
917 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
918 // Rates above the max (510000) should be capped.
919 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000922TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700923 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000924
925 // Test that we can only set a maximum bitrate for a fixed-rate codec
926 // if it's bigger than the fixed rate.
927
928 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700929 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
930 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
931 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
932 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
933 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
934 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
935 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000936}
937
938TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200940 const int kDesiredBitrate = 128000;
941 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700942 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200943 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700944 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000945
946 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800947 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000948
solenberg2100c0b2017-03-01 11:29:29 -0800949 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000950}
951
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952// Test that bitrate cannot be set for CBR codecs.
953// Bitrate is ignored if it is higher than the fixed bitrate.
954// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
958 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700959 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800960 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200961
962 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700963 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800964 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965
966 send_parameters_.max_bandwidth_bps = 128;
967 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800968 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
skvlade0d46372016-04-07 22:59:22 -0700971// Test that the per-stream bitrate limit and the global
972// bitrate limit both apply.
973TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
974 EXPECT_TRUE(SetupSendStream());
975
ossu20a4b3f2017-04-27 02:08:52 -0700976 // opus, default bitrate == 32000.
977 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700978 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
979 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
980 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
981
982 // CBR codecs allow both maximums to exceed the bitrate.
983 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
984 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
985 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
986 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
987
988 // CBR codecs don't allow per stream maximums to be too low.
989 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
990 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
991}
992
993// Test that an attempt to set RtpParameters for a stream that does not exist
994// fails.
995TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
996 EXPECT_TRUE(SetupChannel());
997 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800998 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700999 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1000
1001 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001002 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001003}
1004
1005TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001006 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001007 // This test verifies that setting RtpParameters succeeds only if
1008 // the structure contains exactly one encoding.
1009 // TODO(skvlad): Update this test when we start supporting setting parameters
1010 // for each encoding individually.
1011
1012 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001013 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001014 // Two or more encodings should result in failure.
1015 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001016 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001017 // Zero encodings should also fail.
1018 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001019 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001020}
1021
1022// Changing the SSRC through RtpParameters is not allowed.
1023TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1024 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001025 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001026 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001027 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001028}
1029
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001030// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001031// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001032TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1033 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001034 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001035 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001036 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001037 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001038 ASSERT_EQ(1u, parameters.encodings.size());
1039 ASSERT_TRUE(parameters.encodings[0].active);
1040 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001041 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1042 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001043
1044 // Now change it back to active and verify we resume sending.
1045 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1047 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001048}
1049
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001050// Test that SetRtpSendParameters configures the correct encoding channel for
1051// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001052TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1053 SetupForMultiSendStream();
1054 // Create send streams.
1055 for (uint32_t ssrc : kSsrcs4) {
1056 EXPECT_TRUE(
1057 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1058 }
1059 // Configure one stream to be limited by the stream config, another to be
1060 // limited by the global max, and the third one with no per-stream limit
1061 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001062 SetGlobalMaxBitrate(kOpusCodec, 32000);
1063 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1064 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001065 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1066
ossu20a4b3f2017-04-27 02:08:52 -07001067 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1068 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1069 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001070
1071 // Remove the global cap; the streams should switch to their respective
1072 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001073 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001074 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1075 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1076 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001077}
1078
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001079// Test that GetRtpSendParameters returns the currently configured codecs.
1080TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001081 EXPECT_TRUE(SetupSendStream());
1082 cricket::AudioSendParameters parameters;
1083 parameters.codecs.push_back(kIsacCodec);
1084 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001085 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001086
solenberg2100c0b2017-03-01 11:29:29 -08001087 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001088 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001089 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1090 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001091}
1092
deadbeefcb443432016-12-12 11:12:36 -08001093// Test that GetRtpSendParameters returns an SSRC.
1094TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1095 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001096 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001097 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001098 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001099}
1100
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001101// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001102TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001103 EXPECT_TRUE(SetupSendStream());
1104 cricket::AudioSendParameters parameters;
1105 parameters.codecs.push_back(kIsacCodec);
1106 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001107 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001108
solenberg2100c0b2017-03-01 11:29:29 -08001109 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001110
1111 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001112 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001113
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001114 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001115 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1116 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001117}
1118
minyuececec102017-03-27 13:04:25 -07001119// Test that max_bitrate_bps in send stream config gets updated correctly when
1120// SetRtpSendParameters is called.
1121TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1122 webrtc::test::ScopedFieldTrials override_field_trials(
1123 "WebRTC-Audio-SendSideBwe/Enabled/");
1124 EXPECT_TRUE(SetupSendStream());
1125 cricket::AudioSendParameters send_parameters;
1126 send_parameters.codecs.push_back(kOpusCodec);
1127 SetSendParameters(send_parameters);
1128
1129 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1130 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1131 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1132
1133 constexpr int kMaxBitrateBps = 6000;
1134 rtp_parameters.encodings[0].max_bitrate_bps =
1135 rtc::Optional<int>(kMaxBitrateBps);
1136 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1137
1138 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1139 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1140}
1141
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001142// Test that GetRtpReceiveParameters returns the currently configured codecs.
1143TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1144 EXPECT_TRUE(SetupRecvStream());
1145 cricket::AudioRecvParameters parameters;
1146 parameters.codecs.push_back(kIsacCodec);
1147 parameters.codecs.push_back(kPcmuCodec);
1148 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1149
1150 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001151 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001152 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1153 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1154 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1155}
1156
deadbeefcb443432016-12-12 11:12:36 -08001157// Test that GetRtpReceiveParameters returns an SSRC.
1158TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1159 EXPECT_TRUE(SetupRecvStream());
1160 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001161 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001162 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001163 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001164}
1165
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001166// Test that if we set/get parameters multiple times, we get the same results.
1167TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1168 EXPECT_TRUE(SetupRecvStream());
1169 cricket::AudioRecvParameters parameters;
1170 parameters.codecs.push_back(kIsacCodec);
1171 parameters.codecs.push_back(kPcmuCodec);
1172 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1173
1174 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001175 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001176
1177 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001178 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001179
1180 // ... And this shouldn't change the params returned by
1181 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001182 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1183 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001184}
1185
deadbeef3bc15102017-04-20 19:25:07 -07001186// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1187// aren't signaled. It should return an empty "RtpEncodingParameters" when
1188// configured to receive an unsignaled stream and no packets have been received
1189// yet, and start returning the SSRC once a packet has been received.
1190TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1191 ASSERT_TRUE(SetupChannel());
1192 // Call necessary methods to configure receiving a default stream as
1193 // soon as it arrives.
1194 cricket::AudioRecvParameters parameters;
1195 parameters.codecs.push_back(kIsacCodec);
1196 parameters.codecs.push_back(kPcmuCodec);
1197 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1198
1199 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1200 // stream. Should return nothing.
1201 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1202
1203 // Set a sink for an unsignaled stream.
1204 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1205 // Value of "0" means "unsignaled stream".
1206 channel_->SetRawAudioSink(0, std::move(fake_sink));
1207
1208 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1209 // in this method means "unsignaled stream".
1210 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1211 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1212 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1213
1214 // Receive PCMU packet (SSRC=1).
1215 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1216
1217 // The |ssrc| member should still be unset.
1218 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1219 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1220 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1221}
1222
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223// Test that we apply codecs properly.
1224TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001225 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001226 cricket::AudioSendParameters parameters;
1227 parameters.codecs.push_back(kIsacCodec);
1228 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001229 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001230 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001231 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001232 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001233 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1234 EXPECT_EQ(96, send_codec_spec.payload_type);
1235 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1236 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1237 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1238 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001239 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001240}
1241
ossu20a4b3f2017-04-27 02:08:52 -07001242// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1243// AudioSendStream.
1244TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001245 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001246 cricket::AudioSendParameters parameters;
1247 parameters.codecs.push_back(kIsacCodec);
1248 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001249 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001250 parameters.codecs[0].id = 96;
1251 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001252 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001253 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001254 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001255 // Calling SetSendCodec again with same codec which is already set.
1256 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001257 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001258 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001259}
1260
ossu20a4b3f2017-04-27 02:08:52 -07001261// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1262// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001263
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001264// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001265TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001266 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001267 cricket::AudioSendParameters parameters;
1268 parameters.codecs.push_back(kOpusCodec);
1269 parameters.codecs[0].bitrate = 0;
1270 parameters.codecs[0].clockrate = 50000;
1271 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001272}
1273
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001274// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001275TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001276 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001277 cricket::AudioSendParameters parameters;
1278 parameters.codecs.push_back(kOpusCodec);
1279 parameters.codecs[0].bitrate = 0;
1280 parameters.codecs[0].channels = 0;
1281 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001282}
1283
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001284// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
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(kOpusCodec);
1289 parameters.codecs[0].bitrate = 0;
1290 parameters.codecs[0].channels = 0;
1291 parameters.codecs[0].params["stereo"] = "1";
1292 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293}
1294
1295// Test that if channel is 1 for opus and there's no stereo, we fail.
1296TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001297 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 cricket::AudioSendParameters parameters;
1299 parameters.codecs.push_back(kOpusCodec);
1300 parameters.codecs[0].bitrate = 0;
1301 parameters.codecs[0].channels = 1;
1302 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303}
1304
1305// Test that if channel is 1 for opus and stereo=0, we fail.
1306TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001307 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001308 cricket::AudioSendParameters parameters;
1309 parameters.codecs.push_back(kOpusCodec);
1310 parameters.codecs[0].bitrate = 0;
1311 parameters.codecs[0].channels = 1;
1312 parameters.codecs[0].params["stereo"] = "0";
1313 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001314}
1315
1316// Test that if channel is 1 for opus and stereo=1, we fail.
1317TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001318 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001319 cricket::AudioSendParameters parameters;
1320 parameters.codecs.push_back(kOpusCodec);
1321 parameters.codecs[0].bitrate = 0;
1322 parameters.codecs[0].channels = 1;
1323 parameters.codecs[0].params["stereo"] = "1";
1324 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001325}
1326
ossu20a4b3f2017-04-27 02:08:52 -07001327// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001328TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001329 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001330 cricket::AudioSendParameters parameters;
1331 parameters.codecs.push_back(kOpusCodec);
1332 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001333 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001334 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335}
1336
ossu20a4b3f2017-04-27 02:08:52 -07001337// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001344 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001345 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346}
1347
ossu20a4b3f2017-04-27 02:08:52 -07001348// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001349TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001350 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 cricket::AudioSendParameters parameters;
1352 parameters.codecs.push_back(kOpusCodec);
1353 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001354 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001356 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001357 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001358
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001360 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001361 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001362}
1363
ossu20a4b3f2017-04-27 02:08:52 -07001364// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kOpusCodec);
1369 parameters.codecs[0].bitrate = 0;
1370 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001371 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001372 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001373}
1374
ossu20a4b3f2017-04-27 02:08:52 -07001375// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001376TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001377 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 cricket::AudioSendParameters parameters;
1379 parameters.codecs.push_back(kOpusCodec);
1380 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001381 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001383 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001384 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001385
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001386 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001387 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001388 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001389}
1390
ossu20a4b3f2017-04-27 02:08:52 -07001391// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001393 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 cricket::AudioSendParameters parameters;
1395 parameters.codecs.push_back(kOpusCodec);
1396 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001397 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001398 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1399 EXPECT_EQ(111, spec.payload_type);
1400 EXPECT_EQ(96000, spec.target_bitrate_bps);
1401 EXPECT_EQ("opus", spec.format.name);
1402 EXPECT_EQ(2, spec.format.num_channels);
1403 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404}
1405
ossu20a4b3f2017-04-27 02:08:52 -07001406// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001408 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001409 cricket::AudioSendParameters parameters;
1410 parameters.codecs.push_back(kOpusCodec);
1411 parameters.codecs[0].bitrate = 30000;
1412 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001414 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
ossu20a4b3f2017-04-27 02:08:52 -07001417// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001424 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425}
1426
ossu20a4b3f2017-04-27 02:08:52 -07001427// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001429 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 cricket::AudioSendParameters parameters;
1431 parameters.codecs.push_back(kOpusCodec);
1432 parameters.codecs[0].bitrate = 30000;
1433 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001436}
1437
stefan13f1a0a2016-11-30 07:22:58 -08001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1439 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1440 200000);
1441}
1442
1443TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1444 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1445}
1446
1447TEST_F(WebRtcVoiceEngineTestFake,
1448 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1449 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1450}
1451
1452TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1453 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1454}
1455
1456TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001457 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001458 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1459 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001460 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001461 SetSendParameters(send_parameters_);
1462 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1463 << "Setting max bitrate should keep previous min bitrate.";
1464 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1465 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001466 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001467}
1468
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001469// Test that we can enable NACK with opus as caller.
1470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].AddFeedbackParam(
1475 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1476 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001477 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001478 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001479 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480}
1481
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001482// Test that we can enable NACK with opus as callee.
1483TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001484 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 cricket::AudioSendParameters parameters;
1486 parameters.codecs.push_back(kOpusCodec);
1487 parameters.codecs[0].AddFeedbackParam(
1488 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1489 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001490 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001491 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001492 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001493 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001494
1495 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001496 cricket::StreamParams::CreateLegacy(kSsrcX)));
1497 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001498}
1499
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001500// Test that we can enable NACK on receive streams.
1501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001502 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001503 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001504 cricket::AudioSendParameters parameters;
1505 parameters.codecs.push_back(kOpusCodec);
1506 parameters.codecs[0].AddFeedbackParam(
1507 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1508 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001509 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1510 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001511 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001512 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1513 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
1516// Test that we can disable NACK.
1517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].AddFeedbackParam(
1522 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1523 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001524 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001525 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001526
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 parameters.codecs.clear();
1528 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001529 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001530 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001531}
1532
1533// Test that we can disable NACK on receive streams.
1534TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001535 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001536 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].AddFeedbackParam(
1540 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1541 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001543 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1544 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001545
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 parameters.codecs.clear();
1547 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001548 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001549 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1550 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551}
1552
1553// Test that NACK is enabled on a new receive stream.
1554TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001555 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kIsacCodec);
1558 parameters.codecs.push_back(kCn16000Codec);
1559 parameters.codecs[0].AddFeedbackParam(
1560 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1561 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001562 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001563 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564
solenberg2100c0b2017-03-01 11:29:29 -08001565 EXPECT_TRUE(AddRecvStream(kSsrcY));
1566 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1567 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1568 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569}
1570
stefanba4c0e42016-02-04 04:12:24 -08001571TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001572 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001573 cricket::AudioSendParameters send_parameters;
1574 send_parameters.codecs.push_back(kOpusCodec);
1575 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001577
1578 cricket::AudioRecvParameters recv_parameters;
1579 recv_parameters.codecs.push_back(kIsacCodec);
1580 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_TRUE(AddRecvStream(kSsrcX));
1582 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001583 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001584 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001585
ossudedfd282016-06-14 07:12:39 -07001586 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001587 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001588 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001589 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001590 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001591}
1592
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001593// Test that we can switch back and forth between Opus and ISAC with CN.
1594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001595 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001596
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001597 cricket::AudioSendParameters opus_parameters;
1598 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001600 {
ossu20a4b3f2017-04-27 02:08:52 -07001601 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1602 EXPECT_EQ(111, spec.payload_type);
1603 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001604 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001605
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001606 cricket::AudioSendParameters isac_parameters;
1607 isac_parameters.codecs.push_back(kIsacCodec);
1608 isac_parameters.codecs.push_back(kCn16000Codec);
1609 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001611 {
ossu20a4b3f2017-04-27 02:08:52 -07001612 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1613 EXPECT_EQ(103, spec.payload_type);
1614 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001615 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616
solenberg059fb442016-10-26 05:12:24 -07001617 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001618 {
ossu20a4b3f2017-04-27 02:08:52 -07001619 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1620 EXPECT_EQ(111, spec.payload_type);
1621 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001622 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623}
1624
1625// Test that we handle various ways of specifying bitrate.
1626TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001627 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001628 cricket::AudioSendParameters parameters;
1629 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001630 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001631 {
ossu20a4b3f2017-04-27 02:08:52 -07001632 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1633 EXPECT_EQ(103, spec.payload_type);
1634 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1635 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001636 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001638 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001639 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001640 {
ossu20a4b3f2017-04-27 02:08:52 -07001641 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1642 EXPECT_EQ(103, spec.payload_type);
1643 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1644 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001645 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001647 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001648 {
ossu20a4b3f2017-04-27 02:08:52 -07001649 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1650 EXPECT_EQ(103, spec.payload_type);
1651 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1652 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001653 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001654
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001655 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001656 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001657 {
ossu20a4b3f2017-04-27 02:08:52 -07001658 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1659 EXPECT_EQ(0, spec.payload_type);
1660 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1661 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001662 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001663
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001666 {
ossu20a4b3f2017-04-27 02:08:52 -07001667 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1668 EXPECT_EQ(0, spec.payload_type);
1669 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1670 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001671 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001673 parameters.codecs[0] = kOpusCodec;
1674 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001675 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001676 {
ossu20a4b3f2017-04-27 02:08:52 -07001677 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1678 EXPECT_EQ(111, spec.payload_type);
1679 EXPECT_STREQ("opus", spec.format.name.c_str());
1680 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001681 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001682}
1683
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001684// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001686 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001687 cricket::AudioSendParameters parameters;
1688 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001689}
1690
1691// Test that we can set send codecs even with telephone-event codec as the first
1692// one on the list.
1693TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001694 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001696 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001697 parameters.codecs.push_back(kIsacCodec);
1698 parameters.codecs.push_back(kPcmuCodec);
1699 parameters.codecs[0].id = 98; // DTMF
1700 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001702 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1703 EXPECT_EQ(96, spec.payload_type);
1704 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001705 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001706}
1707
solenberg31642aa2016-03-14 08:00:37 -07001708// Test that payload type range is limited for telephone-event codec.
1709TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001711 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001712 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001713 parameters.codecs.push_back(kIsacCodec);
1714 parameters.codecs[0].id = 0; // DTMF
1715 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001717 EXPECT_TRUE(channel_->CanInsertDtmf());
1718 parameters.codecs[0].id = 128; // DTMF
1719 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1720 EXPECT_FALSE(channel_->CanInsertDtmf());
1721 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001723 EXPECT_TRUE(channel_->CanInsertDtmf());
1724 parameters.codecs[0].id = -1; // DTMF
1725 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1726 EXPECT_FALSE(channel_->CanInsertDtmf());
1727}
1728
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001729// Test that we can set send codecs even with CN codec as the first
1730// one on the list.
1731TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001732 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001733 cricket::AudioSendParameters parameters;
1734 parameters.codecs.push_back(kCn16000Codec);
1735 parameters.codecs.push_back(kIsacCodec);
1736 parameters.codecs.push_back(kPcmuCodec);
1737 parameters.codecs[0].id = 98; // wideband CN
1738 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001739 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001740 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1741 EXPECT_EQ(96, send_codec_spec.payload_type);
1742 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001743 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744}
1745
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001746// Test that we set VAD and DTMF types correctly as caller.
1747TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001748 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters parameters;
1750 parameters.codecs.push_back(kIsacCodec);
1751 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001753 parameters.codecs.push_back(kCn16000Codec);
1754 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001755 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001756 parameters.codecs[0].id = 96;
1757 parameters.codecs[2].id = 97; // wideband CN
1758 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001760 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1761 EXPECT_EQ(96, send_codec_spec.payload_type);
1762 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1763 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001764 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001765 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766}
1767
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001768// Test that we set VAD and DTMF types correctly as callee.
1769TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001770 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 cricket::AudioSendParameters parameters;
1772 parameters.codecs.push_back(kIsacCodec);
1773 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001774 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001775 parameters.codecs.push_back(kCn16000Codec);
1776 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001777 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001778 parameters.codecs[0].id = 96;
1779 parameters.codecs[2].id = 97; // wideband CN
1780 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001781 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001782 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001783 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001784
ossu20a4b3f2017-04-27 02:08:52 -07001785 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1786 EXPECT_EQ(96, send_codec_spec.payload_type);
1787 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1788 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001789 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001790 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001791}
1792
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793// Test that we only apply VAD if we have a CN codec that matches the
1794// send codec clockrate.
1795TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001796 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001799 parameters.codecs.push_back(kIsacCodec);
1800 parameters.codecs.push_back(kCn16000Codec);
1801 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001803 {
ossu20a4b3f2017-04-27 02:08:52 -07001804 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1805 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1806 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001807 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001808 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001810 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001811 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001812 {
ossu20a4b3f2017-04-27 02:08:52 -07001813 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1814 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1815 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001816 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001819 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001820 {
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1823 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001824 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001825 }
Brave Yao5225dd82015-03-26 07:39:19 +08001826 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001829 {
ossu20a4b3f2017-04-27 02:08:52 -07001830 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1831 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1832 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001833 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001834}
1835
1836// Test that we perform case-insensitive matching of codec names.
1837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001838 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 cricket::AudioSendParameters parameters;
1840 parameters.codecs.push_back(kIsacCodec);
1841 parameters.codecs.push_back(kPcmuCodec);
1842 parameters.codecs.push_back(kCn16000Codec);
1843 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001844 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 parameters.codecs[0].name = "iSaC";
1846 parameters.codecs[0].id = 96;
1847 parameters.codecs[2].id = 97; // wideband CN
1848 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001849 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001850 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1851 EXPECT_EQ(96, send_codec_spec.payload_type);
1852 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1853 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001854 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001855 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001856}
1857
stefanba4c0e42016-02-04 04:12:24 -08001858class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1859 public:
1860 WebRtcVoiceEngineWithSendSideBweTest()
1861 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1862};
1863
1864TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1865 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001866 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001867 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001868 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1869 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1870 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001871 extension.id);
1872 return;
1873 }
1874 }
1875 FAIL() << "Transport sequence number extension not in header-extension list.";
1876}
1877
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001878// Test support for audio level header extension.
1879TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001880 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001881}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001882TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001883 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001884}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001885
solenbergd4adce42016-11-17 06:26:52 -08001886// Test support for transport sequence number header extension.
1887TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1888 TestSetSendRtpHeaderExtensions(
1889 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001890}
solenbergd4adce42016-11-17 06:26:52 -08001891TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1892 TestSetRecvRtpHeaderExtensions(
1893 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001894}
1895
solenberg1ac56142015-10-13 03:58:19 -07001896// Test that we can create a channel and start sending on it.
1897TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001898 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001899 SetSendParameters(send_parameters_);
1900 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001901 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001902 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001903 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001904}
1905
1906// Test that a channel will send if and only if it has a source and is enabled
1907// for sending.
1908TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001909 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001910 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001911 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001912 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001913 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1914 SetAudioSend(kSsrcX, true, &fake_source_);
1915 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1916 SetAudioSend(kSsrcX, true, nullptr);
1917 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001918}
1919
solenberg94218532016-06-16 10:53:22 -07001920// Test that a channel is muted/unmuted.
1921TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1922 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001923 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001924 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1925 SetAudioSend(kSsrcX, true, nullptr);
1926 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1927 SetAudioSend(kSsrcX, false, nullptr);
1928 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001929}
1930
solenberg6d6e7c52016-04-13 09:07:30 -07001931// Test that SetSendParameters() does not alter a stream's send state.
1932TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1933 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001934 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001935
1936 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001937 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001938 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001939
1940 // Changing RTP header extensions will recreate the AudioSendStream.
1941 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001942 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001943 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001944 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001945
1946 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001947 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001948 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001949
1950 // Changing RTP header extensions will recreate the AudioSendStream.
1951 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001952 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001953 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001954}
1955
solenberg1ac56142015-10-13 03:58:19 -07001956// Test that we can create a channel and start playing out on it.
1957TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001958 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001959 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001960 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001961 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001962 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001963 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001964}
1965
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001966// Test that we can add and remove send streams.
1967TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1968 SetupForMultiSendStream();
1969
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001970 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001971 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001972
solenbergc96df772015-10-21 13:01:53 -07001973 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001974 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001975 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001976 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001977 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001978 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001979 }
tfarina5237aaf2015-11-10 23:44:30 -08001980 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001981
solenbergc96df772015-10-21 13:01:53 -07001982 // Delete the send streams.
1983 for (uint32_t ssrc : kSsrcs4) {
1984 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001985 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001986 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001987 }
solenbergc96df772015-10-21 13:01:53 -07001988 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001989}
1990
1991// Test SetSendCodecs correctly configure the codecs in all send streams.
1992TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1993 SetupForMultiSendStream();
1994
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07001996 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001997 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001998 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001999 }
2000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002002 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002003 parameters.codecs.push_back(kIsacCodec);
2004 parameters.codecs.push_back(kCn16000Codec);
2005 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002006 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002007
2008 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002009 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002010 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2011 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002012 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2013 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2014 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002015 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002016 }
2017
minyue7a973442016-10-20 03:27:12 -07002018 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002020 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002021 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002022 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2023 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002024 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2025 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2026 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027 }
2028}
2029
2030// Test we can SetSend on all send streams correctly.
2031TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2032 SetupForMultiSendStream();
2033
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002034 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002035 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002037 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002038 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002039 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 }
2041
2042 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002043 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002044 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002046 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002047 }
2048
2049 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002050 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002051 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002053 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054 }
2055}
2056
2057// Test we can set the correct statistics on all send streams.
2058TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2059 SetupForMultiSendStream();
2060
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002062 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002064 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002065 }
solenberg85a04962015-10-27 03:35:21 -07002066
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002067 // Create a receive stream to check that none of the send streams end up in
2068 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002069 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002070
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002072 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002073 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002074 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075
solenberg85a04962015-10-27 03:35:21 -07002076 // Check stats for the added streams.
2077 {
2078 cricket::VoiceMediaInfo info;
2079 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080
solenberg85a04962015-10-27 03:35:21 -07002081 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002082 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002083 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002084 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002085 }
hbos1acfbd22016-11-17 23:43:29 -08002086 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002087
2088 // We have added one receive stream. We should see empty stats.
2089 EXPECT_EQ(info.receivers.size(), 1u);
2090 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002091 }
solenberg1ac56142015-10-13 03:58:19 -07002092
solenberg2100c0b2017-03-01 11:29:29 -08002093 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002094 {
2095 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002096 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002097 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002098 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002099 EXPECT_EQ(0u, info.receivers.size());
2100 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002101
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002102 // Deliver a new packet - a default receive stream should be created and we
2103 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002104 {
2105 cricket::VoiceMediaInfo info;
2106 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2107 SetAudioReceiveStreamStats();
2108 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002109 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002110 EXPECT_EQ(1u, info.receivers.size());
2111 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002112 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002113 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114}
2115
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002116// Test that we can add and remove receive streams, and do proper send/playout.
2117// We can receive on multiple streams while sending one stream.
2118TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002119 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120
solenberg1ac56142015-10-13 03:58:19 -07002121 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002122 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002123 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002124
solenberg1ac56142015-10-13 03:58:19 -07002125 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002126 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002127 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002128 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002129
solenberg1ac56142015-10-13 03:58:19 -07002130 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002131 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132
2133 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002134 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2135 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2136 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137
2138 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002139 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002140 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002141
2142 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002143 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2145 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002146
aleloi84ef6152016-08-04 05:28:21 -07002147 // Restart playout and make sure recv streams are played out.
2148 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002149 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2150 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002151
aleloi84ef6152016-08-04 05:28:21 -07002152 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002153 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2154 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002155}
2156
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002158// and start sending on it.
2159TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002160 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002161 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2162 EXPECT_CALL(apm_gc_,
2163 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002164 SetSendParameters(send_parameters_);
2165 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002166 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002167 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169}
2170
wu@webrtc.org97077a32013-10-25 21:18:33 +00002171TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002172 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002173 EXPECT_CALL(adm_,
2174 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002175 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2176 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002177 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2178 send_parameters_.options.tx_agc_digital_compression_gain =
2179 rtc::Optional<uint16_t>(9);
2180 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2181 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002182 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2183 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2184 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002185 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002186
2187 // Check interaction with adjust_agc_delta. Both should be respected, for
2188 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002189 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002190 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002191 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002192}
2193
wu@webrtc.org97077a32013-10-25 21:18:33 +00002194TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002195 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002196 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2197 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002198 send_parameters_.options.recording_sample_rate =
2199 rtc::Optional<uint32_t>(48000);
2200 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002201 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002202}
2203
minyue6b825df2016-10-31 04:08:32 -07002204TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2205 EXPECT_TRUE(SetupSendStream());
2206 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2207 send_parameters_.options.audio_network_adaptor_config =
2208 rtc::Optional<std::string>("1234");
2209 SetSendParameters(send_parameters_);
2210 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002211 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002212}
2213
2214TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2215 EXPECT_TRUE(SetupSendStream());
2216 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2217 send_parameters_.options.audio_network_adaptor_config =
2218 rtc::Optional<std::string>("1234");
2219 SetSendParameters(send_parameters_);
2220 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002221 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002222 cricket::AudioOptions options;
2223 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002224 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002226}
2227
2228TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2229 EXPECT_TRUE(SetupSendStream());
2230 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2231 send_parameters_.options.audio_network_adaptor_config =
2232 rtc::Optional<std::string>("1234");
2233 SetSendParameters(send_parameters_);
2234 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002235 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002236 const int initial_num = call_.GetNumCreatedSendStreams();
2237 cricket::AudioOptions options;
2238 options.audio_network_adaptor = rtc::Optional<bool>();
2239 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2240 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002241 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002242 // AudioSendStream not expected to be recreated.
2243 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2244 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002245 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002246}
2247
michaelt6672b262017-01-11 10:17:59 -08002248class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2249 : public WebRtcVoiceEngineTestFake {
2250 public:
2251 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2252 : WebRtcVoiceEngineTestFake(
2253 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2254 "Enabled/") {}
2255};
2256
2257TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2258 EXPECT_TRUE(SetupSendStream());
2259 cricket::AudioSendParameters parameters;
2260 parameters.codecs.push_back(kOpusCodec);
2261 SetSendParameters(parameters);
2262 const int initial_num = call_.GetNumCreatedSendStreams();
2263 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2264
2265 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2266 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002267 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2268 constexpr int kMinOverheadBps =
2269 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002270
2271 constexpr int kOpusMinBitrateBps = 6000;
2272 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002273 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002274 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002275 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002276 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002277
2278 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2279 parameters.options.audio_network_adaptor_config =
2280 rtc::Optional<std::string>("1234");
2281 SetSendParameters(parameters);
2282
ossu11bfc532017-02-16 05:37:06 -08002283 constexpr int kMinOverheadWithAnaBps =
2284 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002285
2286 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002287 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002288
minyuececec102017-03-27 13:04:25 -07002289 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002290 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002291}
2292
minyuececec102017-03-27 13:04:25 -07002293// This test is similar to
2294// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2295// additional field trial.
2296TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2297 SetRtpSendParameterUpdatesMaxBitrate) {
2298 EXPECT_TRUE(SetupSendStream());
2299 cricket::AudioSendParameters send_parameters;
2300 send_parameters.codecs.push_back(kOpusCodec);
2301 SetSendParameters(send_parameters);
2302
2303 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2304 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2305 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2306
2307 constexpr int kMaxBitrateBps = 6000;
2308 rtp_parameters.encodings[0].max_bitrate_bps =
2309 rtc::Optional<int>(kMaxBitrateBps);
2310 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2311
2312 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2313#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2314 constexpr int kMinOverhead = 3333;
2315#else
2316 constexpr int kMinOverhead = 6666;
2317#endif
2318 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2319}
2320
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002322// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002324 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002325 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002326}
2327
2328TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2329 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002330 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002331 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002332 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002333 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002334 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002335 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002336 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002337
solenberg85a04962015-10-27 03:35:21 -07002338 // Check stats for the added streams.
2339 {
2340 cricket::VoiceMediaInfo info;
2341 EXPECT_EQ(true, channel_->GetStats(&info));
2342
2343 // We have added one send stream. We should see the stats we've set.
2344 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002345 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002346 // We have added one receive stream. We should see empty stats.
2347 EXPECT_EQ(info.receivers.size(), 1u);
2348 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2349 }
solenberg1ac56142015-10-13 03:58:19 -07002350
solenberg566ef242015-11-06 15:34:49 -08002351 // Start sending - this affects some reported stats.
2352 {
2353 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002354 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002355 EXPECT_EQ(true, channel_->GetStats(&info));
2356 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002357 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002358 }
2359
solenberg2100c0b2017-03-01 11:29:29 -08002360 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002361 {
2362 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002363 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002364 EXPECT_EQ(true, channel_->GetStats(&info));
2365 EXPECT_EQ(1u, info.senders.size());
2366 EXPECT_EQ(0u, info.receivers.size());
2367 }
solenberg1ac56142015-10-13 03:58:19 -07002368
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002369 // Deliver a new packet - a default receive stream should be created and we
2370 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002371 {
2372 cricket::VoiceMediaInfo info;
2373 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2374 SetAudioReceiveStreamStats();
2375 EXPECT_EQ(true, channel_->GetStats(&info));
2376 EXPECT_EQ(1u, info.senders.size());
2377 EXPECT_EQ(1u, info.receivers.size());
2378 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002379 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002380 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381}
2382
2383// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002384// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002386 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002387 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2388 EXPECT_TRUE(AddRecvStream(kSsrcY));
2389 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002390}
2391
2392// Test that the local SSRC is the same on sending and receiving channels if the
2393// receive channel is created before the send channel.
2394TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002395 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002396 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002398 cricket::StreamParams::CreateLegacy(kSsrcX)));
2399 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2400 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401}
2402
2403// Test that we can properly receive packets.
2404TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002405 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002406 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002407 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002408
2409 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2410 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002411}
2412
2413// Test that we can properly receive packets on multiple streams.
2414TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002415 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002416 const uint32_t ssrc1 = 1;
2417 const uint32_t ssrc2 = 2;
2418 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002419 EXPECT_TRUE(AddRecvStream(ssrc1));
2420 EXPECT_TRUE(AddRecvStream(ssrc2));
2421 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002423 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002424 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002426 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427 }
mflodman3d7db262016-04-29 00:57:13 -07002428
2429 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2430 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2431 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2432
2433 EXPECT_EQ(s1.received_packets(), 0);
2434 EXPECT_EQ(s2.received_packets(), 0);
2435 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002436
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002438 EXPECT_EQ(s1.received_packets(), 0);
2439 EXPECT_EQ(s2.received_packets(), 0);
2440 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002441
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002442 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002443 EXPECT_EQ(s1.received_packets(), 1);
2444 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2445 EXPECT_EQ(s2.received_packets(), 0);
2446 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002447
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002449 EXPECT_EQ(s1.received_packets(), 1);
2450 EXPECT_EQ(s2.received_packets(), 1);
2451 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2452 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002453
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002455 EXPECT_EQ(s1.received_packets(), 1);
2456 EXPECT_EQ(s2.received_packets(), 1);
2457 EXPECT_EQ(s3.received_packets(), 1);
2458 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002459
mflodman3d7db262016-04-29 00:57:13 -07002460 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2461 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2462 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463}
2464
solenberg2100c0b2017-03-01 11:29:29 -08002465// Test that receiving on an unsignaled stream works (a stream is created).
2466TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002467 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002468 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2469
solenberg7e63ef02015-11-20 00:19:43 -08002470 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002471
2472 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002473 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2474 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002475}
2476
solenberg2100c0b2017-03-01 11:29:29 -08002477// Test that receiving N unsignaled stream works (streams will be created), and
2478// that packets are forwarded to them all.
2479TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002480 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002481 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002482 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2483
solenberg2100c0b2017-03-01 11:29:29 -08002484 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002485 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002486 rtc::SetBE32(&packet[8], ssrc);
2487 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002488
solenberg2100c0b2017-03-01 11:29:29 -08002489 // Verify we have one new stream for each loop iteration.
2490 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002491 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2492 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002493 }
mflodman3d7db262016-04-29 00:57:13 -07002494
solenberg2100c0b2017-03-01 11:29:29 -08002495 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002496 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002497 rtc::SetBE32(&packet[8], ssrc);
2498 DeliverPacket(packet, sizeof(packet));
2499
solenbergebb349d2017-03-13 05:46:15 -07002500 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002501 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2502 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2503 }
2504
2505 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2506 constexpr uint32_t kAnotherSsrc = 667;
2507 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002508 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002509
2510 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002511 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002512 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002513 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002514 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2515 EXPECT_EQ(2, streams[i]->received_packets());
2516 }
2517 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2518 EXPECT_EQ(1, streams[i]->received_packets());
2519 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002520 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002521}
2522
solenberg2100c0b2017-03-01 11:29:29 -08002523// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002524// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002525TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
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
2530 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002531 const uint32_t signaled_ssrc = 1;
2532 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002533 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002534 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2536 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002537 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002538
2539 // Note that the first unknown SSRC cannot be 0, because we only support
2540 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002541 const uint32_t unsignaled_ssrc = 7011;
2542 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002543 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002544 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2545 packet, sizeof(packet)));
2546 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2547
2548 DeliverPacket(packet, sizeof(packet));
2549 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2550
2551 rtc::SetBE32(&packet[8], signaled_ssrc);
2552 DeliverPacket(packet, sizeof(packet));
2553 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2554 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002555}
2556
solenberg4904fb62017-02-17 12:01:14 -08002557// Two tests to verify that adding a receive stream with the same SSRC as a
2558// previously added unsignaled stream will only recreate underlying stream
2559// objects if the stream parameters have changed.
2560TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2561 EXPECT_TRUE(SetupChannel());
2562
2563 // Spawn unsignaled stream with SSRC=1.
2564 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2565 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2566 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2567 sizeof(kPcmuFrame)));
2568
2569 // Verify that the underlying stream object in Call is not recreated when a
2570 // stream with SSRC=1 is added.
2571 const auto& streams = call_.GetAudioReceiveStreams();
2572 EXPECT_EQ(1, streams.size());
2573 int audio_receive_stream_id = streams.front()->id();
2574 EXPECT_TRUE(AddRecvStream(1));
2575 EXPECT_EQ(1, streams.size());
2576 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2577}
2578
2579TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2580 EXPECT_TRUE(SetupChannel());
2581
2582 // Spawn unsignaled stream with SSRC=1.
2583 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2584 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2585 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2586 sizeof(kPcmuFrame)));
2587
2588 // Verify that the underlying stream object in Call *is* recreated when a
2589 // stream with SSRC=1 is added, and which has changed stream parameters.
2590 const auto& streams = call_.GetAudioReceiveStreams();
2591 EXPECT_EQ(1, streams.size());
2592 int audio_receive_stream_id = streams.front()->id();
2593 cricket::StreamParams stream_params;
2594 stream_params.ssrcs.push_back(1);
2595 stream_params.sync_label = "sync_label";
2596 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2597 EXPECT_EQ(1, streams.size());
2598 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2599}
2600
solenberg0a617e22015-10-20 15:49:38 -07002601// Test that we properly handle failures to add a receive stream.
2602TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002603 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002604 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002605 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002606}
2607
solenberg0a617e22015-10-20 15:49:38 -07002608// Test that we properly handle failures to add a send stream.
2609TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002610 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002611 voe_.set_fail_create_channel(true);
2612 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2613}
2614
solenberg1ac56142015-10-13 03:58:19 -07002615// Test that AddRecvStream creates new stream.
2616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002617 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002618 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002619 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002620 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002621}
2622
2623// Test that after adding a recv stream, we do not decode more codecs than
2624// those previously passed into SetRecvCodecs.
2625TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002626 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002627 cricket::AudioRecvParameters parameters;
2628 parameters.codecs.push_back(kIsacCodec);
2629 parameters.codecs.push_back(kPcmuCodec);
2630 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002631 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002632 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2633 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2634 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002635}
2636
2637// Test that we properly clean up any streams that were added, even if
2638// not explicitly removed.
2639TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002640 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002641 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002642 EXPECT_TRUE(AddRecvStream(1));
2643 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002644 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2645 delete channel_;
2646 channel_ = NULL;
2647 EXPECT_EQ(0, voe_.GetNumChannels());
2648}
2649
wu@webrtc.org78187522013-10-07 23:32:02 +00002650TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002652 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002653}
2654
2655TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002657 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002658 // Manually delete channel to simulate a failure.
2659 int channel = voe_.GetLastChannel();
2660 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2661 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002662 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002663 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002664 EXPECT_NE(channel, new_channel);
2665 // The last created channel is deleted too.
2666 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002667}
2668
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002669// Test the InsertDtmf on default send stream as caller.
2670TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002671 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002672}
2673
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002674// Test the InsertDtmf on default send stream as callee
2675TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002676 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002677}
2678
2679// Test the InsertDtmf on specified send stream as caller.
2680TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002681 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002682}
2683
2684// Test the InsertDtmf on specified send stream as callee.
2685TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002686 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002687}
2688
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002689TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002690 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002691 EXPECT_CALL(adm_,
2692 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2693 EXPECT_CALL(adm_,
2694 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2695 EXPECT_CALL(adm_,
2696 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002697
solenberg246b8172015-12-08 09:50:23 -08002698 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2699 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700
solenberg246b8172015-12-08 09:50:23 -08002701 // Nothing set in AudioOptions, so everything should be as default.
2702 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002703 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002704 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002705 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2706 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002707
2708 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002709 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2710 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002711 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002712 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713
2714 // Turn echo cancellation back on, with settings, and make sure
2715 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002716 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2717 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002718 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002719 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002721 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2722 // control.
solenberg76377c52017-02-21 00:54:31 -08002723 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2724 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002725 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002726 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002727
2728 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002729 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2730 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002731 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2732 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2733 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002734 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002735
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002736 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002737 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2738 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002739 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002740 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002741
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002743 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2744 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2745 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2746 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002747 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002748 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749
2750 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002751 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2752 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2753 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002755 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2756 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002757 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758
2759 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002760 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2765 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2766 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002767 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2768 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2769 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2770 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002771 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002772 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002773
solenberg1ac56142015-10-13 03:58:19 -07002774 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002775 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2781 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783}
2784
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002786 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002787 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002788 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002789 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002790 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002791 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002792 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002793 EXPECT_CALL(adm_,
2794 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2795 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2796 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
2797 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
2798 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002799
kwiberg686a8ef2016-02-26 03:00:35 -08002800 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002801 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002802 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002803 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002804 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002805 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002806
2807 // Have to add a stream to make SetSend work.
2808 cricket::StreamParams stream1;
2809 stream1.ssrcs.push_back(1);
2810 channel1->AddSendStream(stream1);
2811 cricket::StreamParams stream2;
2812 stream2.ssrcs.push_back(2);
2813 channel2->AddSendStream(stream2);
2814
2815 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002816 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002817 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2818 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2819 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002820 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2821 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2822 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2823 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2824 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002825 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002826 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002827 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002828 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002829
2830 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002831 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002832 parameters_options_no_ns.options.noise_suppression =
2833 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002834 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2835 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2836 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2837 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2838 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002839 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002840 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002841 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2842 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2843 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002844 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002845
2846 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002847 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002848 parameters_options_no_agc.options.auto_gain_control =
2849 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002850 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2851 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2852 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2853 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2854 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002855 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002856 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2857 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2858 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002859 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860
solenberg76377c52017-02-21 00:54:31 -08002861 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2863 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2864 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2865 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002866 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867
solenberg76377c52017-02-21 00:54:31 -08002868 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2872 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002873 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
solenberg76377c52017-02-21 00:54:31 -08002875 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2878 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2879 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002880 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002881
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002883 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2884 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002885 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002886 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002887 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002888 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002889 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002894 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002895 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2896 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2897 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002898 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899}
2900
wu@webrtc.orgde305012013-10-31 15:40:38 +00002901// This test verifies DSCP settings are properly applied on voice media channel.
2902TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002903 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002904 cricket::FakeNetworkInterface network_interface;
2905 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002906 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002907
solenberg059fb442016-10-26 05:12:24 -07002908 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
2909 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
2910
solenbergbc37fc82016-04-04 09:54:44 -07002911 channel.reset(
2912 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002913 channel->SetInterface(&network_interface);
2914 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2915 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2916
2917 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002918 channel.reset(
2919 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002920 channel->SetInterface(&network_interface);
2921 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2922
2923 // Verify that setting the option to false resets the
2924 // DiffServCodePoint.
2925 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002926 channel.reset(
2927 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002928 channel->SetInterface(&network_interface);
2929 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2930 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2931
2932 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002933}
2934
solenberg1ac56142015-10-13 03:58:19 -07002935TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002936 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 cricket::WebRtcVoiceMediaChannel* media_channel =
2938 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002939 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002940 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002941 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002942 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2943 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2944 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002945 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002946 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947}
2948
solenberg1ac56142015-10-13 03:58:19 -07002949TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002950 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002951 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002952 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2953 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2954 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002955 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002956 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002957 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2958 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002959 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002960 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002961 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002962 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002963}
2964
solenberg4bac9c52015-10-09 02:32:53 -07002965TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002966 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002967 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002969 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002970 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002971 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2972 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2973 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002974}
2975
solenberg2100c0b2017-03-01 11:29:29 -08002976TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002977 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002978
2979 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002980 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002981 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2982
2983 // Should remember the volume "2" which will be set on new unsignaled streams,
2984 // and also set the gain to 2 on existing unsignaled streams.
2985 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2986 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2987
2988 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2989 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2990 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2991 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2992 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2993 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2994
2995 // Setting gain with SSRC=0 should affect all unsignaled streams.
2996 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002997 if (kMaxUnsignaledRecvStreams > 1) {
2998 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
2999 }
solenberg2100c0b2017-03-01 11:29:29 -08003000 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3001
3002 // Setting gain on an individual stream affects only that.
3003 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003004 if (kMaxUnsignaledRecvStreams > 1) {
3005 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3006 }
solenberg2100c0b2017-03-01 11:29:29 -08003007 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008}
3009
pbos8fc7fa72015-07-15 08:02:58 -07003010TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003011 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003012 const std::string kSyncLabel = "AvSyncLabel";
3013
solenbergff976312016-03-30 23:28:51 -07003014 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003015 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3016 sp.sync_label = kSyncLabel;
3017 // Creating two channels to make sure that sync label is set properly for both
3018 // the default voice channel and following ones.
3019 EXPECT_TRUE(channel_->AddRecvStream(sp));
3020 sp.ssrcs[0] += 1;
3021 EXPECT_TRUE(channel_->AddRecvStream(sp));
3022
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003023 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003024 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003025 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003026 << "SyncGroup should be set based on sync_label";
3027 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003028 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003029 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003030}
3031
solenberg3a941542015-11-16 07:34:50 -08003032// TODO(solenberg): Remove, once recv streams are configured through Call.
3033// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003034TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003035 // Test that setting the header extensions results in the expected state
3036 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003037 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003038 ssrcs.push_back(223);
3039 ssrcs.push_back(224);
3040
solenbergff976312016-03-30 23:28:51 -07003041 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003042 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003043 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003044 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003045 cricket::StreamParams::CreateLegacy(ssrc)));
3046 }
3047
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003048 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003049 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003050 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003051 EXPECT_NE(nullptr, s);
3052 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3053 }
3054
3055 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003056 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003057 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003058 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003059 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003060 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003061 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003062 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003063 EXPECT_NE(nullptr, s);
3064 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003065 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3066 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003067 for (const auto& s_ext : s_exts) {
3068 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003069 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003070 }
3071 }
3072 }
3073 }
3074
3075 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003076 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003077 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003078 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003079 EXPECT_NE(nullptr, s);
3080 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3081 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003082}
3083
3084TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3085 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003086 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003087 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003088 static const unsigned char kRtcp[] = {
3089 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3090 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3093 };
jbaucheec21bd2016-03-20 06:15:43 -07003094 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095
solenbergff976312016-03-30 23:28:51 -07003096 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097 cricket::WebRtcVoiceMediaChannel* media_channel =
3098 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003099 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 EXPECT_TRUE(media_channel->AddRecvStream(
3101 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3102
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003103 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003104 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003105 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003106 EXPECT_EQ(0, s->received_packets());
3107 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3108 EXPECT_EQ(1, s->received_packets());
3109 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3110 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003111}
Minyue2013aec2015-05-13 14:14:42 +02003112
solenberg0a617e22015-10-20 15:49:38 -07003113// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003114// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003115TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003116 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003117 EXPECT_TRUE(AddRecvStream(kSsrcY));
3118 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003119 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003120 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3121 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3122 EXPECT_TRUE(AddRecvStream(kSsrcW));
3123 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003124}
3125
solenberg7602aab2016-11-14 11:30:07 -08003126TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3127 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003128 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003129 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003130 cricket::StreamParams::CreateLegacy(kSsrcY)));
3131 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3132 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3133 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003134 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003135 cricket::StreamParams::CreateLegacy(kSsrcW)));
3136 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3137 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003138}
stefan658910c2015-09-03 05:48:32 -07003139
deadbeef884f5852016-01-15 09:20:04 -08003140TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003141 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003142 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3143 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003144
3145 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003146 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3147 EXPECT_TRUE(AddRecvStream(kSsrcX));
3148 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003149
3150 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003151 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3152 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003153
3154 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003155 channel_->SetRawAudioSink(kSsrcX, nullptr);
3156 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003157}
3158
solenberg2100c0b2017-03-01 11:29:29 -08003159TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003160 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003161 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3162 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003163 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3164 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003165
3166 // Should be able to set a default sink even when no stream exists.
3167 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3168
solenberg2100c0b2017-03-01 11:29:29 -08003169 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3170 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003171 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003172 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003173
3174 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003175 channel_->SetRawAudioSink(kSsrc0, nullptr);
3176 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003177
3178 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003179 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3180 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003181
3182 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003183 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003184 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003185 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3186
3187 // Spawn another unsignaled stream - it should be assigned the default sink
3188 // and the previous unsignaled stream should lose it.
3189 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3190 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3191 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3192 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003193 if (kMaxUnsignaledRecvStreams > 1) {
3194 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3195 }
solenberg2100c0b2017-03-01 11:29:29 -08003196 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3197
3198 // Reset the default sink - the second unsignaled stream should lose it.
3199 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003200 if (kMaxUnsignaledRecvStreams > 1) {
3201 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3202 }
solenberg2100c0b2017-03-01 11:29:29 -08003203 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3204
3205 // Try setting the default sink while two streams exists.
3206 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003207 if (kMaxUnsignaledRecvStreams > 1) {
3208 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3209 }
solenberg2100c0b2017-03-01 11:29:29 -08003210 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3211
3212 // Try setting the sink for the first unsignaled stream using its known SSRC.
3213 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003214 if (kMaxUnsignaledRecvStreams > 1) {
3215 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3216 }
solenberg2100c0b2017-03-01 11:29:29 -08003217 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003218 if (kMaxUnsignaledRecvStreams > 1) {
3219 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3220 }
deadbeef884f5852016-01-15 09:20:04 -08003221}
3222
skvlad7a43d252016-03-22 15:32:27 -07003223// Test that, just like the video channel, the voice channel communicates the
3224// network state to the call.
3225TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003226 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003227
3228 EXPECT_EQ(webrtc::kNetworkUp,
3229 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3230 EXPECT_EQ(webrtc::kNetworkUp,
3231 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3232
3233 channel_->OnReadyToSend(false);
3234 EXPECT_EQ(webrtc::kNetworkDown,
3235 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3236 EXPECT_EQ(webrtc::kNetworkUp,
3237 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3238
3239 channel_->OnReadyToSend(true);
3240 EXPECT_EQ(webrtc::kNetworkUp,
3241 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3242 EXPECT_EQ(webrtc::kNetworkUp,
3243 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3244}
3245
aleloi18e0b672016-10-04 02:45:47 -07003246// Test that playout is still started after changing parameters
3247TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3248 SetupRecvStream();
3249 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003250 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003251
3252 // Changing RTP header extensions will recreate the AudioReceiveStream.
3253 cricket::AudioRecvParameters parameters;
3254 parameters.extensions.push_back(
3255 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3256 channel_->SetRecvParameters(parameters);
3257
solenberg2100c0b2017-03-01 11:29:29 -08003258 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003259}
3260
stefan658910c2015-09-03 05:48:32 -07003261// Tests that the library initializes and shuts down properly.
3262TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003263 // If the VoiceEngine wants to gather available codecs early, that's fine but
3264 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003265 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003266 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3267 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003268 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003269 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003270 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003271 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003272 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3273 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003274 EXPECT_TRUE(channel != nullptr);
3275 delete channel;
solenbergff976312016-03-30 23:28:51 -07003276}
stefan658910c2015-09-03 05:48:32 -07003277
solenbergff976312016-03-30 23:28:51 -07003278// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003279TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3280 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3281 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3282 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003283 // Return 100ms just in case this function gets called. If we don't,
3284 // we could enter a tight loop since the mock would return 0.
3285 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003286 {
ossuc54071d2016-08-17 02:45:41 -07003287 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003288 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3289 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003290 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003291 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003292 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003293 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003294 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3295 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3296 EXPECT_TRUE(channel != nullptr);
3297 delete channel;
3298 }
stefan658910c2015-09-03 05:48:32 -07003299}
3300
ossu20a4b3f2017-04-27 02:08:52 -07003301// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3302TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003303 // TODO(ossu): Why are the payload types of codecs with non-static payload
3304 // type assignments checked here? It shouldn't really matter.
3305 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003306 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3307 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003308 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003309 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003310 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3311 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3312 (clockrate == 0 || codec.clockrate == clockrate);
3313 };
3314 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003315 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003316 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003317 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003318 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003319 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003320 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003321 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003322 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003323 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003324 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003325 EXPECT_EQ(126, codec.id);
3326 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3327 // Remove these checks once both send and receive side assigns payload types
3328 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003329 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003330 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003331 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003332 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003333 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003334 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003335 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003336 EXPECT_EQ(111, codec.id);
3337 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3338 EXPECT_EQ("10", codec.params.find("minptime")->second);
3339 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3340 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003341 }
3342 }
stefan658910c2015-09-03 05:48:32 -07003343}
3344
3345// Tests that VoE supports at least 32 channels
3346TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003347 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003348 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3349 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003350 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003351 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003352 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003353 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003354
3355 cricket::VoiceMediaChannel* channels[32];
3356 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003357 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003358 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3359 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003360 if (!channel)
3361 break;
stefan658910c2015-09-03 05:48:32 -07003362 channels[num_channels++] = channel;
3363 }
3364
tfarina5237aaf2015-11-10 23:44:30 -08003365 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003366 EXPECT_EQ(expected, num_channels);
3367
3368 while (num_channels > 0) {
3369 delete channels[--num_channels];
3370 }
stefan658910c2015-09-03 05:48:32 -07003371}
3372
3373// Test that we set our preferred codecs properly.
3374TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003375 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3376 // - Check that our builtin codecs are usable by Channel.
3377 // - The codecs provided by the engine is usable by Channel.
3378 // It does not check that the codecs in the RecvParameters are actually
3379 // what we sent in - though it's probably reasonable to expect so, if
3380 // SetRecvParameters returns true.
3381 // I think it will become clear once audio decoder injection is completed.
3382 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003383 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3384 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003385 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003386 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003387 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003388 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003389 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3390 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003391 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003392 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003393 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003394}
ossu9def8002017-02-09 05:14:32 -08003395
3396TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3397 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003398 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3399 {48000, 2, 16000, 10000, 20000}};
3400 spec1.info.allow_comfort_noise = false;
3401 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003402 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003403 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3404 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003405 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003406 specs.push_back(webrtc::AudioCodecSpec{
3407 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3408 {16000, 1, 13300}});
3409 specs.push_back(
3410 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3411 specs.push_back(
3412 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003413
ossueb1fde42017-05-02 06:46:30 -07003414 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3415 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3416 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003417 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003418 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003419 .WillOnce(Return(specs));
3420
ossueb1fde42017-05-02 06:46:30 -07003421 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
3422 mock_decoder_factory, nullptr);
deadbeefeb02c032017-06-15 08:29:25 -07003423 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003424 auto codecs = engine.recv_codecs();
3425 EXPECT_EQ(11, codecs.size());
3426
3427 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3428 // check the actual values safely, to provide better test results.
3429 auto get_codec =
3430 [&codecs](size_t index) -> const cricket::AudioCodec& {
3431 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3432 if (codecs.size() > index)
3433 return codecs[index];
3434 return missing_codec;
3435 };
3436
3437 // Ensure the general codecs are generated first and in order.
3438 for (size_t i = 0; i != specs.size(); ++i) {
3439 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3440 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3441 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3442 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3443 }
3444
3445 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003446 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003447 auto find_codec =
3448 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3449 for (size_t i = 0; i != codecs.size(); ++i) {
3450 const cricket::AudioCodec& codec = codecs[i];
3451 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3452 codec.clockrate == format.clockrate_hz &&
3453 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003454 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003455 }
3456 }
3457 return -1;
3458 };
3459
3460 // Ensure all supplementary codecs are generated last. Their internal ordering
3461 // is not important.
3462 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3463 const int num_specs = static_cast<int>(specs.size());
3464 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3465 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3466 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3467 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3468 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3469 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3470 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3471}