blob: f96bf7190370c92da91a7a5c5a8c6665c0be7751 [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));
solenbergff976312016-03-30 23:28:51 -0700138 EXPECT_TRUE(voe.IsInited());
139 }
140 EXPECT_FALSE(voe.IsInited());
141}
142
deadbeef884f5852016-01-15 09:20:04 -0800143class FakeAudioSink : public webrtc::AudioSinkInterface {
144 public:
145 void OnData(const Data& audio) override {}
146};
147
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800148class FakeAudioSource : public cricket::AudioSource {
149 void SetSink(Sink* sink) override {}
150};
151
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152class WebRtcVoiceEngineTestFake : public testing::Test {
153 public:
stefanba4c0e42016-02-04 04:12:24 -0800154 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
155
156 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800157 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
158 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
159 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700160 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800161 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700162 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800163 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700164 EXPECT_CALL(apm_, ApplyConfig(testing::_));
165 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
166 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
aleloi048cbdd2017-05-29 02:56:27 -0700167 EXPECT_CALL(apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800168 // Default Options.
169 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
170 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
171 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
172 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
173 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
174 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
175 // Init does not overwrite default AGC config.
176 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
177 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
178 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
179 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
180 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
181 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700182 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800183 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700184 // factories. Those tests should probably be moved elsewhere.
185 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
186 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
187 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
188 decoder_factory, nullptr,
189 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200190 send_parameters_.codecs.push_back(kPcmuCodec);
191 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800192 // Default Options.
193 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194 }
solenberg8189b022016-06-14 12:13:00 -0700195
solenbergff976312016-03-30 23:28:51 -0700196 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700197 EXPECT_CALL(apm_, ApplyConfig(testing::_));
198 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700199 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
200 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200201 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000202 }
solenberg8189b022016-06-14 12:13:00 -0700203
solenbergff976312016-03-30 23:28:51 -0700204 bool SetupRecvStream() {
205 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700206 return false;
207 }
solenberg2100c0b2017-03-01 11:29:29 -0800208 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700209 }
solenberg8189b022016-06-14 12:13:00 -0700210
solenbergff976312016-03-30 23:28:51 -0700211 bool SetupSendStream() {
212 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000213 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
solenberg2100c0b2017-03-01 11:29:29 -0800215 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800216 return false;
217 }
solenberg059fb442016-10-26 05:12:24 -0700218 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800219 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 }
solenberg8189b022016-06-14 12:13:00 -0700221
222 bool AddRecvStream(uint32_t ssrc) {
223 EXPECT_TRUE(channel_);
224 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
225 }
226
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000227 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700228 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700229 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800230 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
231 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700232 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800233 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000234 }
solenberg8189b022016-06-14 12:13:00 -0700235
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700237 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000238 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 }
solenberg8189b022016-06-14 12:13:00 -0700240
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200241 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 }
244
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100245 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
246 const auto* send_stream = call_.GetAudioSendStream(ssrc);
247 EXPECT_TRUE(send_stream);
248 return *send_stream;
249 }
250
deadbeef884f5852016-01-15 09:20:04 -0800251 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
252 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
253 EXPECT_TRUE(recv_stream);
254 return *recv_stream;
255 }
256
solenberg3a941542015-11-16 07:34:50 -0800257 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800258 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800259 }
260
solenberg7add0582015-11-20 09:59:34 -0800261 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800262 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800263 }
264
solenberg059fb442016-10-26 05:12:24 -0700265 void SetSend(bool enable) {
266 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700267 if (enable) {
268 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
269 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
270 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700271 EXPECT_CALL(apm_, ApplyConfig(testing::_));
272 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700273 }
solenberg059fb442016-10-26 05:12:24 -0700274 channel_->SetSend(enable);
275 }
276
277 void SetSendParameters(const cricket::AudioSendParameters& params) {
278 EXPECT_CALL(apm_, ApplyConfig(testing::_));
279 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
280 ASSERT_TRUE(channel_);
281 EXPECT_TRUE(channel_->SetSendParameters(params));
282 }
283
minyue6b825df2016-10-31 04:08:32 -0700284 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
285 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700286 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
287 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700288 if (enable && options) {
289 EXPECT_CALL(apm_, ApplyConfig(testing::_));
290 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
291 }
292 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700293 }
294
solenbergffbbcac2016-11-17 05:25:37 -0800295 void TestInsertDtmf(uint32_t ssrc, bool caller,
296 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700297 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000298 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700299 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000300 // send stream.
301 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800302 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000303 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000304
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700306 SetSendParameters(send_parameters_);
307 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800309 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800310 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700311 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313
314 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700315 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800316 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800318 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000319 }
320
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800322 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100324 // Test send.
325 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800326 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100327 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800328 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800329 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800330 EXPECT_EQ(codec.id, telephone_event.payload_type);
331 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100332 EXPECT_EQ(2, telephone_event.event_code);
333 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 }
335
336 // Test that send bandwidth is set correctly.
337 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000338 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
339 // |expected_result| is the expected result from SetMaxSendBandwidth().
340 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700341 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
342 int max_bitrate,
343 bool expected_result,
344 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200345 cricket::AudioSendParameters parameters;
346 parameters.codecs.push_back(codec);
347 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700348 if (expected_result) {
349 SetSendParameters(parameters);
350 } else {
351 EXPECT_FALSE(channel_->SetSendParameters(parameters));
352 }
solenberg2100c0b2017-03-01 11:29:29 -0800353 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 }
355
skvlade0d46372016-04-07 22:59:22 -0700356 // Sets the per-stream maximum bitrate limit for the specified SSRC.
357 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700358 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700359 EXPECT_EQ(1UL, parameters.encodings.size());
360
deadbeefe702b302017-02-04 12:09:01 -0800361 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700362 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700363 }
364
solenberg059fb442016-10-26 05:12:24 -0700365 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700366 cricket::AudioSendParameters send_parameters;
367 send_parameters.codecs.push_back(codec);
368 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700369 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700370 }
371
ossu20a4b3f2017-04-27 02:08:52 -0700372 void CheckSendCodecBitrate(int32_t ssrc,
373 const char expected_name[],
374 int expected_bitrate) {
375 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
376 EXPECT_EQ(expected_name, spec->format.name);
377 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700378 }
379
ossu20a4b3f2017-04-27 02:08:52 -0700380 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
381 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700382 }
383
minyue6b825df2016-10-31 04:08:32 -0700384 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
385 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
386 }
387
skvlade0d46372016-04-07 22:59:22 -0700388 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
389 int global_max,
390 int stream_max,
391 bool expected_result,
392 int expected_codec_bitrate) {
393 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800394 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700395
396 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700397 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800398 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700399
400 // Verify that reading back the parameters gives results
401 // consistent with the Set() result.
402 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800403 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700404 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
405 EXPECT_EQ(expected_result ? stream_max : -1,
406 resulting_parameters.encodings[0].max_bitrate_bps);
407
408 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800409 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700410 }
411
stefan13f1a0a2016-11-30 07:22:58 -0800412 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
413 int expected_min_bitrate_bps,
414 const char* start_bitrate_kbps,
415 int expected_start_bitrate_bps,
416 const char* max_bitrate_kbps,
417 int expected_max_bitrate_bps) {
418 EXPECT_TRUE(SetupSendStream());
419 auto& codecs = send_parameters_.codecs;
420 codecs.clear();
421 codecs.push_back(kOpusCodec);
422 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
423 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
424 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
425 SetSendParameters(send_parameters_);
426
427 EXPECT_EQ(expected_min_bitrate_bps,
428 call_.GetConfig().bitrate_config.min_bitrate_bps);
429 EXPECT_EQ(expected_start_bitrate_bps,
430 call_.GetConfig().bitrate_config.start_bitrate_bps);
431 EXPECT_EQ(expected_max_bitrate_bps,
432 call_.GetConfig().bitrate_config.max_bitrate_bps);
433 }
434
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000435 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700436 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000437
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000438 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800439 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000440
441 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700442 send_parameters_.extensions.push_back(
443 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700444 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800445 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000446
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000447 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200448 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700449 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000452 // Ensure extension is set properly.
453 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
457 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
458 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000459
solenberg7add0582015-11-20 09:59:34 -0800460 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000461 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800462 cricket::StreamParams::CreateLegacy(kSsrcY)));
463 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
464 call_.GetAudioSendStream(kSsrcY));
465 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
466 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
467 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000468
469 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200470 send_parameters_.codecs.push_back(kPcmuCodec);
471 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700472 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800473 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
474 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000475 }
476
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000477 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700478 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800481 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482
483 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700484 recv_parameters_.extensions.push_back(
485 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800486 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800487 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800490 recv_parameters_.extensions.clear();
491 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000494 // Ensure extension is set properly.
495 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
499 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
500 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000501
solenberg7add0582015-11-20 09:59:34 -0800502 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_TRUE(AddRecvStream(kSsrcY));
504 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
505 call_.GetAudioReceiveStream(kSsrcY));
506 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
507 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
508 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000509
510 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800511 recv_parameters_.extensions.clear();
512 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800513 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
514 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000515 }
516
solenberg85a04962015-10-27 03:35:21 -0700517 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
518 webrtc::AudioSendStream::Stats stats;
519 stats.local_ssrc = 12;
520 stats.bytes_sent = 345;
521 stats.packets_sent = 678;
522 stats.packets_lost = 9012;
523 stats.fraction_lost = 34.56f;
524 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800525 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700526 stats.ext_seqnum = 789;
527 stats.jitter_ms = 12;
528 stats.rtt_ms = 345;
529 stats.audio_level = 678;
530 stats.aec_quality_min = 9.01f;
531 stats.echo_delay_median_ms = 234;
532 stats.echo_delay_std_ms = 567;
533 stats.echo_return_loss = 890;
534 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700535 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800536 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700537 stats.typing_noise_detected = true;
538 return stats;
539 }
540 void SetAudioSendStreamStats() {
541 for (auto* s : call_.GetAudioSendStreams()) {
542 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200543 }
solenberg85a04962015-10-27 03:35:21 -0700544 }
solenberg566ef242015-11-06 15:34:49 -0800545 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
546 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700547 const auto stats = GetAudioSendStreamStats();
548 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
549 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
550 EXPECT_EQ(info.packets_sent, stats.packets_sent);
551 EXPECT_EQ(info.packets_lost, stats.packets_lost);
552 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
553 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800554 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700555 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
556 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
557 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
558 EXPECT_EQ(info.audio_level, stats.audio_level);
559 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
560 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
561 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
562 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
563 EXPECT_EQ(info.echo_return_loss_enhancement,
564 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700565 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800566 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
567 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800568 EXPECT_EQ(info.typing_noise_detected,
569 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700570 }
571
572 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
573 webrtc::AudioReceiveStream::Stats stats;
574 stats.remote_ssrc = 123;
575 stats.bytes_rcvd = 456;
576 stats.packets_rcvd = 768;
577 stats.packets_lost = 101;
578 stats.fraction_lost = 23.45f;
579 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800580 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700581 stats.ext_seqnum = 678;
582 stats.jitter_ms = 901;
583 stats.jitter_buffer_ms = 234;
584 stats.jitter_buffer_preferred_ms = 567;
585 stats.delay_estimate_ms = 890;
586 stats.audio_level = 1234;
587 stats.expand_rate = 5.67f;
588 stats.speech_expand_rate = 8.90f;
589 stats.secondary_decoded_rate = 1.23f;
590 stats.accelerate_rate = 4.56f;
591 stats.preemptive_expand_rate = 7.89f;
592 stats.decoding_calls_to_silence_generator = 12;
593 stats.decoding_calls_to_neteq = 345;
594 stats.decoding_normal = 67890;
595 stats.decoding_plc = 1234;
596 stats.decoding_cng = 5678;
597 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700598 stats.decoding_muted_output = 3456;
599 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200600 return stats;
601 }
602 void SetAudioReceiveStreamStats() {
603 for (auto* s : call_.GetAudioReceiveStreams()) {
604 s->SetStats(GetAudioReceiveStreamStats());
605 }
606 }
607 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700608 const auto stats = GetAudioReceiveStreamStats();
609 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
610 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
611 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
612 EXPECT_EQ(info.packets_lost, stats.packets_lost);
613 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
614 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800615 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700616 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
617 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
618 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200619 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700620 stats.jitter_buffer_preferred_ms);
621 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
622 EXPECT_EQ(info.audio_level, stats.audio_level);
623 EXPECT_EQ(info.expand_rate, stats.expand_rate);
624 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
625 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
626 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
627 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200628 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700629 stats.decoding_calls_to_silence_generator);
630 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
631 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
632 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
633 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
634 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700635 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700636 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200637 }
hbos1acfbd22016-11-17 23:43:29 -0800638 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
639 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
640 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
641 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
642 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
643 codec.ToCodecParameters());
644 }
645 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
646 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
647 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
648 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
649 codec.ToCodecParameters());
650 }
651 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200652
peah8271d042016-11-22 07:24:52 -0800653 bool IsHighPassFilterEnabled() {
654 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
655 }
656
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700658 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700659 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800660 webrtc::test::MockGainControl& apm_gc_;
661 webrtc::test::MockEchoCancellation& apm_ec_;
662 webrtc::test::MockNoiseSuppression& apm_ns_;
663 webrtc::test::MockVoiceDetection& apm_vd_;
664 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700665 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200666 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700668 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700669 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200670 cricket::AudioSendParameters send_parameters_;
671 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800672 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800673 private:
674 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675};
676
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000677// Tests that we can create and destroy a channel.
678TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700679 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680}
681
solenberg31fec402016-05-06 02:13:12 -0700682// Test that we can add a send stream and that it has the correct defaults.
683TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
684 EXPECT_TRUE(SetupChannel());
685 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800686 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
687 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
688 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700689 EXPECT_EQ("", config.rtp.c_name);
690 EXPECT_EQ(0u, config.rtp.extensions.size());
691 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
692 config.send_transport);
693}
694
695// Test that we can add a receive stream and that it has the correct defaults.
696TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
697 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800698 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700699 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800700 GetRecvStreamConfig(kSsrcX);
701 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700702 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
703 EXPECT_FALSE(config.rtp.transport_cc);
704 EXPECT_EQ(0u, config.rtp.extensions.size());
705 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
706 config.rtcp_send_transport);
707 EXPECT_EQ("", config.sync_group);
708}
709
stefanba4c0e42016-02-04 04:12:24 -0800710TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700711 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800712 bool opus_found = false;
713 for (cricket::AudioCodec codec : codecs) {
714 if (codec.name == "opus") {
715 EXPECT_TRUE(HasTransportCc(codec));
716 opus_found = true;
717 }
718 }
719 EXPECT_TRUE(opus_found);
720}
721
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722// Test that we set our inbound codecs properly, including changing PT.
723TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700724 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200725 cricket::AudioRecvParameters parameters;
726 parameters.codecs.push_back(kIsacCodec);
727 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800728 parameters.codecs.push_back(kTelephoneEventCodec1);
729 parameters.codecs.push_back(kTelephoneEventCodec2);
730 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200731 parameters.codecs[2].id = 126;
732 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800733 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700734 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
735 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
736 {{0, {"PCMU", 8000, 1}},
737 {106, {"ISAC", 16000, 1}},
738 {126, {"telephone-event", 8000, 1}},
739 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740}
741
742// Test that we fail to set an unknown inbound codec.
743TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700744 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200745 cricket::AudioRecvParameters parameters;
746 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700747 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200748 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000749}
750
751// Test that we fail if we have duplicate types in the inbound list.
752TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700753 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200754 cricket::AudioRecvParameters parameters;
755 parameters.codecs.push_back(kIsacCodec);
756 parameters.codecs.push_back(kCn16000Codec);
757 parameters.codecs[1].id = kIsacCodec.id;
758 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759}
760
761// Test that we can decode OPUS without stereo parameters.
762TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700763 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200764 cricket::AudioRecvParameters parameters;
765 parameters.codecs.push_back(kIsacCodec);
766 parameters.codecs.push_back(kPcmuCodec);
767 parameters.codecs.push_back(kOpusCodec);
768 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800769 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700770 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
771 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
772 {{0, {"PCMU", 8000, 1}},
773 {103, {"ISAC", 16000, 1}},
774 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775}
776
777// Test that we can decode OPUS with stereo = 0.
778TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700779 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200780 cricket::AudioRecvParameters parameters;
781 parameters.codecs.push_back(kIsacCodec);
782 parameters.codecs.push_back(kPcmuCodec);
783 parameters.codecs.push_back(kOpusCodec);
784 parameters.codecs[2].params["stereo"] = "0";
785 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800786 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700787 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
788 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
789 {{0, {"PCMU", 8000, 1}},
790 {103, {"ISAC", 16000, 1}},
791 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792}
793
794// Test that we can decode OPUS with stereo = 1.
795TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700796 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 cricket::AudioRecvParameters parameters;
798 parameters.codecs.push_back(kIsacCodec);
799 parameters.codecs.push_back(kPcmuCodec);
800 parameters.codecs.push_back(kOpusCodec);
801 parameters.codecs[2].params["stereo"] = "1";
802 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800803 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700804 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
805 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
806 {{0, {"PCMU", 8000, 1}},
807 {103, {"ISAC", 16000, 1}},
808 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809}
810
811// Test that changes to recv codecs are applied to all streams.
812TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200814 cricket::AudioRecvParameters parameters;
815 parameters.codecs.push_back(kIsacCodec);
816 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800817 parameters.codecs.push_back(kTelephoneEventCodec1);
818 parameters.codecs.push_back(kTelephoneEventCodec2);
819 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200820 parameters.codecs[2].id = 126;
821 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700822 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
823 EXPECT_TRUE(AddRecvStream(ssrc));
824 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
825 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
826 {{0, {"PCMU", 8000, 1}},
827 {106, {"ISAC", 16000, 1}},
828 {126, {"telephone-event", 8000, 1}},
829 {107, {"telephone-event", 32000, 1}}})));
830 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831}
832
833TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700834 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200835 cricket::AudioRecvParameters parameters;
836 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800837 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200838 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839
solenberg2100c0b2017-03-01 11:29:29 -0800840 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800841 ASSERT_EQ(1, dm.count(106));
842 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843}
844
845// Test that we can apply the same set of codecs again while playing.
846TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700847 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200848 cricket::AudioRecvParameters parameters;
849 parameters.codecs.push_back(kIsacCodec);
850 parameters.codecs.push_back(kCn16000Codec);
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700852 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200853 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854
deadbeefcb383672017-04-26 16:28:42 -0700855 // Remapping a payload type to a different codec should fail.
856 parameters.codecs[0] = kOpusCodec;
857 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800859 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860}
861
862// Test that we can add a codec while playing.
863TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700864 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200865 cricket::AudioRecvParameters parameters;
866 parameters.codecs.push_back(kIsacCodec);
867 parameters.codecs.push_back(kCn16000Codec);
868 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700869 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 parameters.codecs.push_back(kOpusCodec);
872 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800873 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874}
875
deadbeefcb383672017-04-26 16:28:42 -0700876// Test that we accept adding the same codec with a different payload type.
877// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
878TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
879 EXPECT_TRUE(SetupRecvStream());
880 cricket::AudioRecvParameters parameters;
881 parameters.codecs.push_back(kIsacCodec);
882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
883
884 ++parameters.codecs[0].id;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
886}
887
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700889 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000891 // Test that when autobw is enabled, bitrate is kept as the default
892 // value. autobw is enabled for the following tests because the target
893 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894
895 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700896 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897
898 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700899 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
ossu20a4b3f2017-04-27 02:08:52 -0700901 // opus, default bitrate == 32000 in mono.
902 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903}
904
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000905TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700906 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700909 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
910 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700911 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700914 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
915 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
916 // Rates above the max (510000) should be capped.
917 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918}
919
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000920TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700921 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000922
923 // Test that we can only set a maximum bitrate for a fixed-rate codec
924 // if it's bigger than the fixed rate.
925
926 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700927 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
928 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
929 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
930 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
931 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
932 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
933 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000934}
935
936TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700937 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200938 const int kDesiredBitrate = 128000;
939 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700940 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200941 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700942 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000943
944 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800945 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000946
solenberg2100c0b2017-03-01 11:29:29 -0800947 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000948}
949
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950// Test that bitrate cannot be set for CBR codecs.
951// Bitrate is ignored if it is higher than the fixed bitrate.
952// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000953TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700954 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955
956 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700957 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800958 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200959
960 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700961 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800962 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200963
964 send_parameters_.max_bandwidth_bps = 128;
965 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800966 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
skvlade0d46372016-04-07 22:59:22 -0700969// Test that the per-stream bitrate limit and the global
970// bitrate limit both apply.
971TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
972 EXPECT_TRUE(SetupSendStream());
973
ossu20a4b3f2017-04-27 02:08:52 -0700974 // opus, default bitrate == 32000.
975 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700976 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
977 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
978 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
979
980 // CBR codecs allow both maximums to exceed the bitrate.
981 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
982 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
983 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
984 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
985
986 // CBR codecs don't allow per stream maximums to be too low.
987 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
988 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
989}
990
991// Test that an attempt to set RtpParameters for a stream that does not exist
992// fails.
993TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
994 EXPECT_TRUE(SetupChannel());
995 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800996 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700997 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
998
999 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001000 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001001}
1002
1003TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001004 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001005 // This test verifies that setting RtpParameters succeeds only if
1006 // the structure contains exactly one encoding.
1007 // TODO(skvlad): Update this test when we start supporting setting parameters
1008 // for each encoding individually.
1009
1010 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001011 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001012 // Two or more encodings should result in failure.
1013 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001014 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001015 // Zero encodings should also fail.
1016 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001017 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001018}
1019
1020// Changing the SSRC through RtpParameters is not allowed.
1021TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1022 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001023 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001024 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001025 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001026}
1027
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001028// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001029// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001030TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1031 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001032 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001033 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001034 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001035 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001036 ASSERT_EQ(1u, parameters.encodings.size());
1037 ASSERT_TRUE(parameters.encodings[0].active);
1038 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001039 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1040 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001041
1042 // Now change it back to active and verify we resume sending.
1043 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001044 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1045 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001046}
1047
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001048// Test that SetRtpSendParameters configures the correct encoding channel for
1049// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001050TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1051 SetupForMultiSendStream();
1052 // Create send streams.
1053 for (uint32_t ssrc : kSsrcs4) {
1054 EXPECT_TRUE(
1055 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1056 }
1057 // Configure one stream to be limited by the stream config, another to be
1058 // limited by the global max, and the third one with no per-stream limit
1059 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001060 SetGlobalMaxBitrate(kOpusCodec, 32000);
1061 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1062 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001063 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1064
ossu20a4b3f2017-04-27 02:08:52 -07001065 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1066 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1067 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001068
1069 // Remove the global cap; the streams should switch to their respective
1070 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001071 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001072 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1073 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1074 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001075}
1076
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001077// Test that GetRtpSendParameters returns the currently configured codecs.
1078TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001079 EXPECT_TRUE(SetupSendStream());
1080 cricket::AudioSendParameters parameters;
1081 parameters.codecs.push_back(kIsacCodec);
1082 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001083 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001084
solenberg2100c0b2017-03-01 11:29:29 -08001085 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001086 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001087 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1088 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001089}
1090
deadbeefcb443432016-12-12 11:12:36 -08001091// Test that GetRtpSendParameters returns an SSRC.
1092TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1093 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001094 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001095 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001096 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001097}
1098
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001099// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001100TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001101 EXPECT_TRUE(SetupSendStream());
1102 cricket::AudioSendParameters parameters;
1103 parameters.codecs.push_back(kIsacCodec);
1104 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001105 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001106
solenberg2100c0b2017-03-01 11:29:29 -08001107 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001108
1109 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001110 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001111
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001112 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001113 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1114 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001115}
1116
minyuececec102017-03-27 13:04:25 -07001117// Test that max_bitrate_bps in send stream config gets updated correctly when
1118// SetRtpSendParameters is called.
1119TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1120 webrtc::test::ScopedFieldTrials override_field_trials(
1121 "WebRTC-Audio-SendSideBwe/Enabled/");
1122 EXPECT_TRUE(SetupSendStream());
1123 cricket::AudioSendParameters send_parameters;
1124 send_parameters.codecs.push_back(kOpusCodec);
1125 SetSendParameters(send_parameters);
1126
1127 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1128 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1129 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1130
1131 constexpr int kMaxBitrateBps = 6000;
1132 rtp_parameters.encodings[0].max_bitrate_bps =
1133 rtc::Optional<int>(kMaxBitrateBps);
1134 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1135
1136 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1137 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1138}
1139
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140// Test that GetRtpReceiveParameters returns the currently configured codecs.
1141TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1142 EXPECT_TRUE(SetupRecvStream());
1143 cricket::AudioRecvParameters parameters;
1144 parameters.codecs.push_back(kIsacCodec);
1145 parameters.codecs.push_back(kPcmuCodec);
1146 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1147
1148 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001149 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1151 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1152 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1153}
1154
deadbeefcb443432016-12-12 11:12:36 -08001155// Test that GetRtpReceiveParameters returns an SSRC.
1156TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1157 EXPECT_TRUE(SetupRecvStream());
1158 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001159 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001160 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001161 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001162}
1163
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164// Test that if we set/get parameters multiple times, we get the same results.
1165TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1166 EXPECT_TRUE(SetupRecvStream());
1167 cricket::AudioRecvParameters parameters;
1168 parameters.codecs.push_back(kIsacCodec);
1169 parameters.codecs.push_back(kPcmuCodec);
1170 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1171
1172 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001173 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001174
1175 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001176 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001177
1178 // ... And this shouldn't change the params returned by
1179 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001180 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1181 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001182}
1183
deadbeef3bc15102017-04-20 19:25:07 -07001184// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1185// aren't signaled. It should return an empty "RtpEncodingParameters" when
1186// configured to receive an unsignaled stream and no packets have been received
1187// yet, and start returning the SSRC once a packet has been received.
1188TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1189 ASSERT_TRUE(SetupChannel());
1190 // Call necessary methods to configure receiving a default stream as
1191 // soon as it arrives.
1192 cricket::AudioRecvParameters parameters;
1193 parameters.codecs.push_back(kIsacCodec);
1194 parameters.codecs.push_back(kPcmuCodec);
1195 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1196
1197 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1198 // stream. Should return nothing.
1199 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1200
1201 // Set a sink for an unsignaled stream.
1202 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1203 // Value of "0" means "unsignaled stream".
1204 channel_->SetRawAudioSink(0, std::move(fake_sink));
1205
1206 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1207 // in this method means "unsignaled stream".
1208 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1209 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1210 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1211
1212 // Receive PCMU packet (SSRC=1).
1213 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1214
1215 // The |ssrc| member should still be unset.
1216 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1217 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1218 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1219}
1220
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221// Test that we apply codecs properly.
1222TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001223 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001224 cricket::AudioSendParameters parameters;
1225 parameters.codecs.push_back(kIsacCodec);
1226 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001227 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001228 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001229 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001230 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001231 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1232 EXPECT_EQ(96, send_codec_spec.payload_type);
1233 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1234 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1235 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1236 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001237 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001238}
1239
ossu20a4b3f2017-04-27 02:08:52 -07001240// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1241// AudioSendStream.
1242TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001243 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001244 cricket::AudioSendParameters parameters;
1245 parameters.codecs.push_back(kIsacCodec);
1246 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001247 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001248 parameters.codecs[0].id = 96;
1249 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001250 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001251 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001252 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001253 // Calling SetSendCodec again with same codec which is already set.
1254 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001255 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001256 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001257}
1258
ossu20a4b3f2017-04-27 02:08:52 -07001259// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1260// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001261
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001262// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001263TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001264 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001265 cricket::AudioSendParameters parameters;
1266 parameters.codecs.push_back(kOpusCodec);
1267 parameters.codecs[0].bitrate = 0;
1268 parameters.codecs[0].clockrate = 50000;
1269 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001270}
1271
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001272// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001273TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001274 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001275 cricket::AudioSendParameters parameters;
1276 parameters.codecs.push_back(kOpusCodec);
1277 parameters.codecs[0].bitrate = 0;
1278 parameters.codecs[0].channels = 0;
1279 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280}
1281
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001282// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kOpusCodec);
1287 parameters.codecs[0].bitrate = 0;
1288 parameters.codecs[0].channels = 0;
1289 parameters.codecs[0].params["stereo"] = "1";
1290 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291}
1292
1293// Test that if channel is 1 for opus and there's no stereo, we fail.
1294TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001295 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001296 cricket::AudioSendParameters parameters;
1297 parameters.codecs.push_back(kOpusCodec);
1298 parameters.codecs[0].bitrate = 0;
1299 parameters.codecs[0].channels = 1;
1300 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
1303// Test that if channel is 1 for opus and stereo=0, we fail.
1304TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001305 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001306 cricket::AudioSendParameters parameters;
1307 parameters.codecs.push_back(kOpusCodec);
1308 parameters.codecs[0].bitrate = 0;
1309 parameters.codecs[0].channels = 1;
1310 parameters.codecs[0].params["stereo"] = "0";
1311 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312}
1313
1314// Test that if channel is 1 for opus and stereo=1, we fail.
1315TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001316 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001317 cricket::AudioSendParameters parameters;
1318 parameters.codecs.push_back(kOpusCodec);
1319 parameters.codecs[0].bitrate = 0;
1320 parameters.codecs[0].channels = 1;
1321 parameters.codecs[0].params["stereo"] = "1";
1322 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323}
1324
ossu20a4b3f2017-04-27 02:08:52 -07001325// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001327 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 cricket::AudioSendParameters parameters;
1329 parameters.codecs.push_back(kOpusCodec);
1330 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001331 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001332 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
ossu20a4b3f2017-04-27 02:08:52 -07001335// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001342 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001343 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344}
1345
ossu20a4b3f2017-04-27 02:08:52 -07001346// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001347TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001348 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001352 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001353 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001354 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001355 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001356
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001357 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001358 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001359 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001360}
1361
ossu20a4b3f2017-04-27 02:08:52 -07001362// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001363TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001364 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001365 cricket::AudioSendParameters parameters;
1366 parameters.codecs.push_back(kOpusCodec);
1367 parameters.codecs[0].bitrate = 0;
1368 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001369 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001370 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001371}
1372
ossu20a4b3f2017-04-27 02:08:52 -07001373// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001374TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001375 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001376 cricket::AudioSendParameters parameters;
1377 parameters.codecs.push_back(kOpusCodec);
1378 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001379 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001381 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001382 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001383
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001385 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001386 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001387}
1388
ossu20a4b3f2017-04-27 02:08:52 -07001389// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001390TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001391 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 cricket::AudioSendParameters parameters;
1393 parameters.codecs.push_back(kOpusCodec);
1394 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001396 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1397 EXPECT_EQ(111, spec.payload_type);
1398 EXPECT_EQ(96000, spec.target_bitrate_bps);
1399 EXPECT_EQ("opus", spec.format.name);
1400 EXPECT_EQ(2, spec.format.num_channels);
1401 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402}
1403
ossu20a4b3f2017-04-27 02:08:52 -07001404// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001405TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001406 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 cricket::AudioSendParameters parameters;
1408 parameters.codecs.push_back(kOpusCodec);
1409 parameters.codecs[0].bitrate = 30000;
1410 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001411 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001412 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413}
1414
ossu20a4b3f2017-04-27 02:08:52 -07001415// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001417 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 cricket::AudioSendParameters parameters;
1419 parameters.codecs.push_back(kOpusCodec);
1420 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423}
1424
ossu20a4b3f2017-04-27 02:08:52 -07001425// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 30000;
1431 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001434}
1435
stefan13f1a0a2016-11-30 07:22:58 -08001436TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1437 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1438 200000);
1439}
1440
1441TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1442 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1443}
1444
1445TEST_F(WebRtcVoiceEngineTestFake,
1446 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1447 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1448}
1449
1450TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1451 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1452}
1453
1454TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001455 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001456 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1457 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001458 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001459 SetSendParameters(send_parameters_);
1460 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1461 << "Setting max bitrate should keep previous min bitrate.";
1462 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1463 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001464 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001465}
1466
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001467// Test that we can enable NACK with opus as caller.
1468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001469 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 cricket::AudioSendParameters parameters;
1471 parameters.codecs.push_back(kOpusCodec);
1472 parameters.codecs[0].AddFeedbackParam(
1473 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1474 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001475 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001476 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001477 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001478}
1479
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001480// Test that we can enable NACK with opus as callee.
1481TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001482 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001483 cricket::AudioSendParameters parameters;
1484 parameters.codecs.push_back(kOpusCodec);
1485 parameters.codecs[0].AddFeedbackParam(
1486 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1487 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001488 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001489 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001490 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001491 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001492
1493 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001494 cricket::StreamParams::CreateLegacy(kSsrcX)));
1495 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001496}
1497
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498// Test that we can enable NACK on receive streams.
1499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001500 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001501 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 cricket::AudioSendParameters parameters;
1503 parameters.codecs.push_back(kOpusCodec);
1504 parameters.codecs[0].AddFeedbackParam(
1505 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1506 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001507 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1508 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001509 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001510 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1511 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512}
1513
1514// Test that we can disable NACK.
1515TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001516 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001517 cricket::AudioSendParameters parameters;
1518 parameters.codecs.push_back(kOpusCodec);
1519 parameters.codecs[0].AddFeedbackParam(
1520 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1521 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001523 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001525 parameters.codecs.clear();
1526 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001527 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001528 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001529}
1530
1531// Test that we can disable NACK on receive streams.
1532TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001533 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001534 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].AddFeedbackParam(
1538 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1539 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1542 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 parameters.codecs.clear();
1545 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001546 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001547 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1548 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001549}
1550
1551// Test that NACK is enabled on a new receive stream.
1552TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001553 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 cricket::AudioSendParameters parameters;
1555 parameters.codecs.push_back(kIsacCodec);
1556 parameters.codecs.push_back(kCn16000Codec);
1557 parameters.codecs[0].AddFeedbackParam(
1558 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1559 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562
solenberg2100c0b2017-03-01 11:29:29 -08001563 EXPECT_TRUE(AddRecvStream(kSsrcY));
1564 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1565 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1566 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001567}
1568
stefanba4c0e42016-02-04 04:12:24 -08001569TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001570 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001571 cricket::AudioSendParameters send_parameters;
1572 send_parameters.codecs.push_back(kOpusCodec);
1573 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001575
1576 cricket::AudioRecvParameters recv_parameters;
1577 recv_parameters.codecs.push_back(kIsacCodec);
1578 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001579 EXPECT_TRUE(AddRecvStream(kSsrcX));
1580 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001581 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001582 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001583
ossudedfd282016-06-14 07:12:39 -07001584 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001585 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001586 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001587 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001588 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001589}
1590
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001591// Test that we can switch back and forth between Opus and ISAC with CN.
1592TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001593 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001594
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001595 cricket::AudioSendParameters opus_parameters;
1596 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001597 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001598 {
ossu20a4b3f2017-04-27 02:08:52 -07001599 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1600 EXPECT_EQ(111, spec.payload_type);
1601 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001602 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001604 cricket::AudioSendParameters isac_parameters;
1605 isac_parameters.codecs.push_back(kIsacCodec);
1606 isac_parameters.codecs.push_back(kCn16000Codec);
1607 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001608 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001609 {
ossu20a4b3f2017-04-27 02:08:52 -07001610 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1611 EXPECT_EQ(103, spec.payload_type);
1612 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001613 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001616 {
ossu20a4b3f2017-04-27 02:08:52 -07001617 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1618 EXPECT_EQ(111, spec.payload_type);
1619 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001620 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621}
1622
1623// Test that we handle various ways of specifying bitrate.
1624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001625 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001626 cricket::AudioSendParameters parameters;
1627 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001628 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001629 {
ossu20a4b3f2017-04-27 02:08:52 -07001630 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1631 EXPECT_EQ(103, spec.payload_type);
1632 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1633 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001634 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001635
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001636 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001638 {
ossu20a4b3f2017-04-27 02:08:52 -07001639 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1640 EXPECT_EQ(103, spec.payload_type);
1641 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1642 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001643 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001645 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001646 {
ossu20a4b3f2017-04-27 02:08:52 -07001647 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1648 EXPECT_EQ(103, spec.payload_type);
1649 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1650 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001651 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001652
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001654 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001655 {
ossu20a4b3f2017-04-27 02:08:52 -07001656 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1657 EXPECT_EQ(0, spec.payload_type);
1658 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1659 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001660 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001663 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001664 {
ossu20a4b3f2017-04-27 02:08:52 -07001665 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1666 EXPECT_EQ(0, spec.payload_type);
1667 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1668 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001669 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 parameters.codecs[0] = kOpusCodec;
1672 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001674 {
ossu20a4b3f2017-04-27 02:08:52 -07001675 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1676 EXPECT_EQ(111, spec.payload_type);
1677 EXPECT_STREQ("opus", spec.format.name.c_str());
1678 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001679 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680}
1681
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001682// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001684 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 cricket::AudioSendParameters parameters;
1686 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001687}
1688
1689// Test that we can set send codecs even with telephone-event codec as the first
1690// one on the list.
1691TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001692 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001694 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 parameters.codecs.push_back(kIsacCodec);
1696 parameters.codecs.push_back(kPcmuCodec);
1697 parameters.codecs[0].id = 98; // DTMF
1698 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001699 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001700 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1701 EXPECT_EQ(96, spec.payload_type);
1702 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001703 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001704}
1705
solenberg31642aa2016-03-14 08:00:37 -07001706// Test that payload type range is limited for telephone-event codec.
1707TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001708 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001709 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001710 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001711 parameters.codecs.push_back(kIsacCodec);
1712 parameters.codecs[0].id = 0; // DTMF
1713 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001715 EXPECT_TRUE(channel_->CanInsertDtmf());
1716 parameters.codecs[0].id = 128; // DTMF
1717 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1718 EXPECT_FALSE(channel_->CanInsertDtmf());
1719 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001720 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001721 EXPECT_TRUE(channel_->CanInsertDtmf());
1722 parameters.codecs[0].id = -1; // DTMF
1723 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1724 EXPECT_FALSE(channel_->CanInsertDtmf());
1725}
1726
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001727// Test that we can set send codecs even with CN codec as the first
1728// one on the list.
1729TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001730 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 cricket::AudioSendParameters parameters;
1732 parameters.codecs.push_back(kCn16000Codec);
1733 parameters.codecs.push_back(kIsacCodec);
1734 parameters.codecs.push_back(kPcmuCodec);
1735 parameters.codecs[0].id = 98; // wideband CN
1736 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001737 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001738 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1739 EXPECT_EQ(96, send_codec_spec.payload_type);
1740 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001741 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001742}
1743
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001744// Test that we set VAD and DTMF types correctly as caller.
1745TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001746 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 cricket::AudioSendParameters parameters;
1748 parameters.codecs.push_back(kIsacCodec);
1749 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 parameters.codecs.push_back(kCn16000Codec);
1752 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001753 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001754 parameters.codecs[0].id = 96;
1755 parameters.codecs[2].id = 97; // wideband CN
1756 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001758 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1759 EXPECT_EQ(96, send_codec_spec.payload_type);
1760 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1761 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001762 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001763 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764}
1765
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001766// Test that we set VAD and DTMF types correctly as callee.
1767TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001768 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001769 cricket::AudioSendParameters parameters;
1770 parameters.codecs.push_back(kIsacCodec);
1771 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001772 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001773 parameters.codecs.push_back(kCn16000Codec);
1774 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001775 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 parameters.codecs[0].id = 96;
1777 parameters.codecs[2].id = 97; // wideband CN
1778 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001779 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001780 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001781 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001782
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(96, send_codec_spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1786 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001787 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001788 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001789}
1790
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001791// Test that we only apply VAD if we have a CN codec that matches the
1792// send codec clockrate.
1793TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001794 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 parameters.codecs.push_back(kIsacCodec);
1798 parameters.codecs.push_back(kCn16000Codec);
1799 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001800 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001801 {
ossu20a4b3f2017-04-27 02:08:52 -07001802 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1803 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1804 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001805 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001806 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001808 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001809 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001810 {
ossu20a4b3f2017-04-27 02:08:52 -07001811 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1812 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1813 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001814 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001818 {
ossu20a4b3f2017-04-27 02:08:52 -07001819 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1820 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1821 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001822 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001823 }
Brave Yao5225dd82015-03-26 07:39:19 +08001824 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001827 {
ossu20a4b3f2017-04-27 02:08:52 -07001828 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1829 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1830 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832}
1833
1834// Test that we perform case-insensitive matching of codec names.
1835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001836 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001837 cricket::AudioSendParameters parameters;
1838 parameters.codecs.push_back(kIsacCodec);
1839 parameters.codecs.push_back(kPcmuCodec);
1840 parameters.codecs.push_back(kCn16000Codec);
1841 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001842 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 parameters.codecs[0].name = "iSaC";
1844 parameters.codecs[0].id = 96;
1845 parameters.codecs[2].id = 97; // wideband CN
1846 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001847 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001848 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1849 EXPECT_EQ(96, send_codec_spec.payload_type);
1850 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1851 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001852 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001853 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854}
1855
stefanba4c0e42016-02-04 04:12:24 -08001856class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1857 public:
1858 WebRtcVoiceEngineWithSendSideBweTest()
1859 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1860};
1861
1862TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1863 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001864 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001865 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001866 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1867 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1868 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001869 extension.id);
1870 return;
1871 }
1872 }
1873 FAIL() << "Transport sequence number extension not in header-extension list.";
1874}
1875
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001876// Test support for audio level header extension.
1877TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001878 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001879}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001880TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001881 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001882}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001883
solenbergd4adce42016-11-17 06:26:52 -08001884// Test support for transport sequence number header extension.
1885TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1886 TestSetSendRtpHeaderExtensions(
1887 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001888}
solenbergd4adce42016-11-17 06:26:52 -08001889TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1890 TestSetRecvRtpHeaderExtensions(
1891 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001892}
1893
solenberg1ac56142015-10-13 03:58:19 -07001894// Test that we can create a channel and start sending on it.
1895TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001896 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(send_parameters_);
1898 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001899 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001900 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001901 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001902}
1903
1904// Test that a channel will send if and only if it has a source and is enabled
1905// for sending.
1906TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001907 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001908 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001909 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001910 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001911 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1912 SetAudioSend(kSsrcX, true, &fake_source_);
1913 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1914 SetAudioSend(kSsrcX, true, nullptr);
1915 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001916}
1917
solenberg94218532016-06-16 10:53:22 -07001918// Test that a channel is muted/unmuted.
1919TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1920 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001921 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001922 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1923 SetAudioSend(kSsrcX, true, nullptr);
1924 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1925 SetAudioSend(kSsrcX, false, nullptr);
1926 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001927}
1928
solenberg6d6e7c52016-04-13 09:07:30 -07001929// Test that SetSendParameters() does not alter a stream's send state.
1930TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1931 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001932 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001933
1934 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001935 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001936 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001937
1938 // Changing RTP header extensions will recreate the AudioSendStream.
1939 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001940 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001942 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001943
1944 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001945 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001946 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001947
1948 // Changing RTP header extensions will recreate the AudioSendStream.
1949 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001951 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001952}
1953
solenberg1ac56142015-10-13 03:58:19 -07001954// Test that we can create a channel and start playing out on it.
1955TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001956 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001957 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001958 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001959 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001960 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001961 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001962}
1963
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001964// Test that we can add and remove send streams.
1965TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1966 SetupForMultiSendStream();
1967
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001968 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001969 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001970
solenbergc96df772015-10-21 13:01:53 -07001971 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001972 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001973 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001974 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001975 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001976 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001977 }
tfarina5237aaf2015-11-10 23:44:30 -08001978 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001979
solenbergc96df772015-10-21 13:01:53 -07001980 // Delete the send streams.
1981 for (uint32_t ssrc : kSsrcs4) {
1982 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001983 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001984 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001985 }
solenbergc96df772015-10-21 13:01:53 -07001986 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001987}
1988
1989// Test SetSendCodecs correctly configure the codecs in all send streams.
1990TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1991 SetupForMultiSendStream();
1992
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001993 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07001994 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001996 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001997 }
1998
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002000 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 parameters.codecs.push_back(kIsacCodec);
2002 parameters.codecs.push_back(kCn16000Codec);
2003 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002005
2006 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002007 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002008 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2009 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002010 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2011 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2012 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002013 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014 }
2015
minyue7a973442016-10-20 03:27:12 -07002016 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002017 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002018 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002019 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002020 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2021 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002022 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2023 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2024 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002025 }
2026}
2027
2028// Test we can SetSend on all send streams correctly.
2029TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2030 SetupForMultiSendStream();
2031
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002032 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002033 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002035 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002036 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002037 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038 }
2039
2040 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002041 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002042 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002044 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 }
2046
2047 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002048 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002049 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002051 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 }
2053}
2054
2055// Test we can set the correct statistics on all send streams.
2056TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2057 SetupForMultiSendStream();
2058
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002060 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002062 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 }
solenberg85a04962015-10-27 03:35:21 -07002064
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002065 // Create a receive stream to check that none of the send streams end up in
2066 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002067 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002068
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002070 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002071 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002072 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073
solenberg85a04962015-10-27 03:35:21 -07002074 // Check stats for the added streams.
2075 {
2076 cricket::VoiceMediaInfo info;
2077 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002078
solenberg85a04962015-10-27 03:35:21 -07002079 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002080 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002081 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002082 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002083 }
hbos1acfbd22016-11-17 23:43:29 -08002084 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002085
2086 // We have added one receive stream. We should see empty stats.
2087 EXPECT_EQ(info.receivers.size(), 1u);
2088 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
solenberg1ac56142015-10-13 03:58:19 -07002090
solenberg2100c0b2017-03-01 11:29:29 -08002091 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002092 {
2093 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002094 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002095 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002096 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002097 EXPECT_EQ(0u, info.receivers.size());
2098 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002099
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002100 // Deliver a new packet - a default receive stream should be created and we
2101 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002102 {
2103 cricket::VoiceMediaInfo info;
2104 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2105 SetAudioReceiveStreamStats();
2106 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002107 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002108 EXPECT_EQ(1u, info.receivers.size());
2109 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002110 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002111 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112}
2113
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114// Test that we can add and remove receive streams, and do proper send/playout.
2115// We can receive on multiple streams while sending one stream.
2116TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002117 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118
solenberg1ac56142015-10-13 03:58:19 -07002119 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002121 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122
solenberg1ac56142015-10-13 03:58:19 -07002123 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002124 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002125 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002126 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127
solenberg1ac56142015-10-13 03:58:19 -07002128 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002129 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130
2131 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002132 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2133 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2134 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002135
2136 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002137 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002138 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002139
2140 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002141 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002142 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2143 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002144
aleloi84ef6152016-08-04 05:28:21 -07002145 // Restart playout and make sure recv streams are played out.
2146 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002147 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2148 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002149
aleloi84ef6152016-08-04 05:28:21 -07002150 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002151 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2152 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153}
2154
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002155// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002156// and start sending on it.
2157TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002158 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002159 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2160 EXPECT_CALL(apm_gc_,
2161 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002162 SetSendParameters(send_parameters_);
2163 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002164 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002165 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002166 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167}
2168
wu@webrtc.org97077a32013-10-25 21:18:33 +00002169TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002170 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002171 EXPECT_CALL(adm_,
2172 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002173 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2174 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002175 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2176 send_parameters_.options.tx_agc_digital_compression_gain =
2177 rtc::Optional<uint16_t>(9);
2178 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2179 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002180 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2181 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2182 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002183 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002184
2185 // Check interaction with adjust_agc_delta. Both should be respected, for
2186 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002187 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002188 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002189 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002190}
2191
wu@webrtc.org97077a32013-10-25 21:18:33 +00002192TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002193 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002194 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2195 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002196 send_parameters_.options.recording_sample_rate =
2197 rtc::Optional<uint32_t>(48000);
2198 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002199 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002200}
2201
minyue6b825df2016-10-31 04:08:32 -07002202TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2203 EXPECT_TRUE(SetupSendStream());
2204 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2205 send_parameters_.options.audio_network_adaptor_config =
2206 rtc::Optional<std::string>("1234");
2207 SetSendParameters(send_parameters_);
2208 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002209 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002210}
2211
2212TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2213 EXPECT_TRUE(SetupSendStream());
2214 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2215 send_parameters_.options.audio_network_adaptor_config =
2216 rtc::Optional<std::string>("1234");
2217 SetSendParameters(send_parameters_);
2218 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002219 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002220 cricket::AudioOptions options;
2221 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002222 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002223 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002224}
2225
2226TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2227 EXPECT_TRUE(SetupSendStream());
2228 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2229 send_parameters_.options.audio_network_adaptor_config =
2230 rtc::Optional<std::string>("1234");
2231 SetSendParameters(send_parameters_);
2232 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002233 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002234 const int initial_num = call_.GetNumCreatedSendStreams();
2235 cricket::AudioOptions options;
2236 options.audio_network_adaptor = rtc::Optional<bool>();
2237 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2238 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002239 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002240 // AudioSendStream not expected to be recreated.
2241 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2242 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002243 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002244}
2245
michaelt6672b262017-01-11 10:17:59 -08002246class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2247 : public WebRtcVoiceEngineTestFake {
2248 public:
2249 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2250 : WebRtcVoiceEngineTestFake(
2251 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2252 "Enabled/") {}
2253};
2254
2255TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2256 EXPECT_TRUE(SetupSendStream());
2257 cricket::AudioSendParameters parameters;
2258 parameters.codecs.push_back(kOpusCodec);
2259 SetSendParameters(parameters);
2260 const int initial_num = call_.GetNumCreatedSendStreams();
2261 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2262
2263 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2264 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002265 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2266 constexpr int kMinOverheadBps =
2267 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002268
2269 constexpr int kOpusMinBitrateBps = 6000;
2270 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002271 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002272 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002273 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002274 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002275
2276 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2277 parameters.options.audio_network_adaptor_config =
2278 rtc::Optional<std::string>("1234");
2279 SetSendParameters(parameters);
2280
ossu11bfc532017-02-16 05:37:06 -08002281 constexpr int kMinOverheadWithAnaBps =
2282 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002283
2284 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002285 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002286
minyuececec102017-03-27 13:04:25 -07002287 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002288 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002289}
2290
minyuececec102017-03-27 13:04:25 -07002291// This test is similar to
2292// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2293// additional field trial.
2294TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2295 SetRtpSendParameterUpdatesMaxBitrate) {
2296 EXPECT_TRUE(SetupSendStream());
2297 cricket::AudioSendParameters send_parameters;
2298 send_parameters.codecs.push_back(kOpusCodec);
2299 SetSendParameters(send_parameters);
2300
2301 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2302 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2303 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2304
2305 constexpr int kMaxBitrateBps = 6000;
2306 rtp_parameters.encodings[0].max_bitrate_bps =
2307 rtc::Optional<int>(kMaxBitrateBps);
2308 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2309
2310 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2311#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2312 constexpr int kMinOverhead = 3333;
2313#else
2314 constexpr int kMinOverhead = 6666;
2315#endif
2316 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2317}
2318
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002319// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002320// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002322 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002323 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002324}
2325
2326TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2327 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002328 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002329 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002330 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002331 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002332 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002333 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002334 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002335
solenberg85a04962015-10-27 03:35:21 -07002336 // Check stats for the added streams.
2337 {
2338 cricket::VoiceMediaInfo info;
2339 EXPECT_EQ(true, channel_->GetStats(&info));
2340
2341 // We have added one send stream. We should see the stats we've set.
2342 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002343 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002344 // We have added one receive stream. We should see empty stats.
2345 EXPECT_EQ(info.receivers.size(), 1u);
2346 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2347 }
solenberg1ac56142015-10-13 03:58:19 -07002348
solenberg566ef242015-11-06 15:34:49 -08002349 // Start sending - this affects some reported stats.
2350 {
2351 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002352 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002353 EXPECT_EQ(true, channel_->GetStats(&info));
2354 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002355 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002356 }
2357
solenberg2100c0b2017-03-01 11:29:29 -08002358 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002359 {
2360 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002361 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002362 EXPECT_EQ(true, channel_->GetStats(&info));
2363 EXPECT_EQ(1u, info.senders.size());
2364 EXPECT_EQ(0u, info.receivers.size());
2365 }
solenberg1ac56142015-10-13 03:58:19 -07002366
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002367 // Deliver a new packet - a default receive stream should be created and we
2368 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002369 {
2370 cricket::VoiceMediaInfo info;
2371 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2372 SetAudioReceiveStreamStats();
2373 EXPECT_EQ(true, channel_->GetStats(&info));
2374 EXPECT_EQ(1u, info.senders.size());
2375 EXPECT_EQ(1u, info.receivers.size());
2376 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002377 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002378 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002379}
2380
2381// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002382// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002383TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002384 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002385 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2386 EXPECT_TRUE(AddRecvStream(kSsrcY));
2387 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388}
2389
2390// Test that the local SSRC is the same on sending and receiving channels if the
2391// receive channel is created before the send channel.
2392TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002393 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002394 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002395 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002396 cricket::StreamParams::CreateLegacy(kSsrcX)));
2397 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2398 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002399}
2400
2401// Test that we can properly receive packets.
2402TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002403 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002404 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002405 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002406
2407 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2408 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409}
2410
2411// Test that we can properly receive packets on multiple streams.
2412TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002413 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002414 const uint32_t ssrc1 = 1;
2415 const uint32_t ssrc2 = 2;
2416 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002417 EXPECT_TRUE(AddRecvStream(ssrc1));
2418 EXPECT_TRUE(AddRecvStream(ssrc2));
2419 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002420 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002421 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002422 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002424 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425 }
mflodman3d7db262016-04-29 00:57:13 -07002426
2427 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2428 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2429 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2430
2431 EXPECT_EQ(s1.received_packets(), 0);
2432 EXPECT_EQ(s2.received_packets(), 0);
2433 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002434
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002436 EXPECT_EQ(s1.received_packets(), 0);
2437 EXPECT_EQ(s2.received_packets(), 0);
2438 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002439
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002441 EXPECT_EQ(s1.received_packets(), 1);
2442 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2443 EXPECT_EQ(s2.received_packets(), 0);
2444 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002445
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002447 EXPECT_EQ(s1.received_packets(), 1);
2448 EXPECT_EQ(s2.received_packets(), 1);
2449 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2450 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002451
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002453 EXPECT_EQ(s1.received_packets(), 1);
2454 EXPECT_EQ(s2.received_packets(), 1);
2455 EXPECT_EQ(s3.received_packets(), 1);
2456 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002457
mflodman3d7db262016-04-29 00:57:13 -07002458 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2459 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2460 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461}
2462
solenberg2100c0b2017-03-01 11:29:29 -08002463// Test that receiving on an unsignaled stream works (a stream is created).
2464TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002465 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002466 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2467
solenberg7e63ef02015-11-20 00:19:43 -08002468 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002469
2470 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002471 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2472 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002473}
2474
solenberg2100c0b2017-03-01 11:29:29 -08002475// Test that receiving N unsignaled stream works (streams will be created), and
2476// that packets are forwarded to them all.
2477TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002478 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002479 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002480 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2481
solenberg2100c0b2017-03-01 11:29:29 -08002482 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002483 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002484 rtc::SetBE32(&packet[8], ssrc);
2485 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002486
solenberg2100c0b2017-03-01 11:29:29 -08002487 // Verify we have one new stream for each loop iteration.
2488 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002489 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2490 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002491 }
mflodman3d7db262016-04-29 00:57:13 -07002492
solenberg2100c0b2017-03-01 11:29:29 -08002493 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002494 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002495 rtc::SetBE32(&packet[8], ssrc);
2496 DeliverPacket(packet, sizeof(packet));
2497
solenbergebb349d2017-03-13 05:46:15 -07002498 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002499 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2500 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2501 }
2502
2503 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2504 constexpr uint32_t kAnotherSsrc = 667;
2505 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002506 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002507
2508 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002509 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002510 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002511 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002512 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2513 EXPECT_EQ(2, streams[i]->received_packets());
2514 }
2515 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2516 EXPECT_EQ(1, streams[i]->received_packets());
2517 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002518 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002519}
2520
solenberg2100c0b2017-03-01 11:29:29 -08002521// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002522// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002523TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002524 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002525 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002526 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2527
2528 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002529 const uint32_t signaled_ssrc = 1;
2530 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002531 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002532 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002533 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2534 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002535 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002536
2537 // Note that the first unknown SSRC cannot be 0, because we only support
2538 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002539 const uint32_t unsignaled_ssrc = 7011;
2540 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002541 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002542 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2543 packet, sizeof(packet)));
2544 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2545
2546 DeliverPacket(packet, sizeof(packet));
2547 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2548
2549 rtc::SetBE32(&packet[8], signaled_ssrc);
2550 DeliverPacket(packet, sizeof(packet));
2551 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2552 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002553}
2554
solenberg4904fb62017-02-17 12:01:14 -08002555// Two tests to verify that adding a receive stream with the same SSRC as a
2556// previously added unsignaled stream will only recreate underlying stream
2557// objects if the stream parameters have changed.
2558TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2559 EXPECT_TRUE(SetupChannel());
2560
2561 // Spawn unsignaled stream with SSRC=1.
2562 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2563 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2564 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2565 sizeof(kPcmuFrame)));
2566
2567 // Verify that the underlying stream object in Call is not recreated when a
2568 // stream with SSRC=1 is added.
2569 const auto& streams = call_.GetAudioReceiveStreams();
2570 EXPECT_EQ(1, streams.size());
2571 int audio_receive_stream_id = streams.front()->id();
2572 EXPECT_TRUE(AddRecvStream(1));
2573 EXPECT_EQ(1, streams.size());
2574 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2575}
2576
2577TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2578 EXPECT_TRUE(SetupChannel());
2579
2580 // Spawn unsignaled stream with SSRC=1.
2581 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2582 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2583 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2584 sizeof(kPcmuFrame)));
2585
2586 // Verify that the underlying stream object in Call *is* recreated when a
2587 // stream with SSRC=1 is added, and which has changed stream parameters.
2588 const auto& streams = call_.GetAudioReceiveStreams();
2589 EXPECT_EQ(1, streams.size());
2590 int audio_receive_stream_id = streams.front()->id();
2591 cricket::StreamParams stream_params;
2592 stream_params.ssrcs.push_back(1);
2593 stream_params.sync_label = "sync_label";
2594 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2595 EXPECT_EQ(1, streams.size());
2596 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2597}
2598
solenberg0a617e22015-10-20 15:49:38 -07002599// Test that we properly handle failures to add a receive stream.
2600TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002601 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002602 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002603 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002604}
2605
solenberg0a617e22015-10-20 15:49:38 -07002606// Test that we properly handle failures to add a send stream.
2607TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002608 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002609 voe_.set_fail_create_channel(true);
2610 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2611}
2612
solenberg1ac56142015-10-13 03:58:19 -07002613// Test that AddRecvStream creates new stream.
2614TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002615 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002616 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002617 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002618 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002619}
2620
2621// Test that after adding a recv stream, we do not decode more codecs than
2622// those previously passed into SetRecvCodecs.
2623TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002624 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002625 cricket::AudioRecvParameters parameters;
2626 parameters.codecs.push_back(kIsacCodec);
2627 parameters.codecs.push_back(kPcmuCodec);
2628 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002629 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002630 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2631 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2632 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002633}
2634
2635// Test that we properly clean up any streams that were added, even if
2636// not explicitly removed.
2637TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002638 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002639 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002640 EXPECT_TRUE(AddRecvStream(1));
2641 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2643 delete channel_;
2644 channel_ = NULL;
2645 EXPECT_EQ(0, voe_.GetNumChannels());
2646}
2647
wu@webrtc.org78187522013-10-07 23:32:02 +00002648TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002649 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002650 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002651}
2652
2653TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002654 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002655 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002656 // Manually delete channel to simulate a failure.
2657 int channel = voe_.GetLastChannel();
2658 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2659 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002660 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002661 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002662 EXPECT_NE(channel, new_channel);
2663 // The last created channel is deleted too.
2664 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002665}
2666
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002667// Test the InsertDtmf on default send stream as caller.
2668TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002669 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002670}
2671
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002672// Test the InsertDtmf on default send stream as callee
2673TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002674 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002675}
2676
2677// Test the InsertDtmf on specified send stream as caller.
2678TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002679 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002680}
2681
2682// Test the InsertDtmf on specified send stream as callee.
2683TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002684 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685}
2686
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002687TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002689 EXPECT_CALL(adm_,
2690 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2691 EXPECT_CALL(adm_,
2692 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2693 EXPECT_CALL(adm_,
2694 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002695
solenberg246b8172015-12-08 09:50:23 -08002696 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2697 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002698
solenberg246b8172015-12-08 09:50:23 -08002699 // Nothing set in AudioOptions, so everything should be as default.
2700 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002701 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002702 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002703 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2704 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705
2706 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002707 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2708 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002709 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002710 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002711
2712 // Turn echo cancellation back on, with settings, and make sure
2713 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002714 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2715 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002716 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002717 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002719 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2720 // control.
solenberg76377c52017-02-21 00:54:31 -08002721 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2722 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002723 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002724 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002725
2726 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002727 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2728 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002729 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2730 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2731 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002732 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002733
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002734 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002735 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2736 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002737 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002738 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002739
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002741 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2743 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2744 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002745 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002746 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747
2748 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002749 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2750 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2751 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2752 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002753 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2754 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002755 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002756
2757 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002758 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2759 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2760 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2764 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002765 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2766 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2767 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2768 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002769 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002770 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002771
solenberg1ac56142015-10-13 03:58:19 -07002772 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002773 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2774 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2775 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2779 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002780 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781}
2782
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002784 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002785 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002786 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002787 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002788 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002789 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002790 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002791 EXPECT_CALL(adm_,
2792 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2793 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2794 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
2795 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
2796 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002797
kwiberg686a8ef2016-02-26 03:00:35 -08002798 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002799 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002800 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002801 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002802 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002803 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804
2805 // Have to add a stream to make SetSend work.
2806 cricket::StreamParams stream1;
2807 stream1.ssrcs.push_back(1);
2808 channel1->AddSendStream(stream1);
2809 cricket::StreamParams stream2;
2810 stream2.ssrcs.push_back(2);
2811 channel2->AddSendStream(stream2);
2812
2813 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002814 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002815 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2816 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2817 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002818 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2819 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2820 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2821 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2822 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002823 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002824 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002825 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002826 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827
2828 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002829 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002830 parameters_options_no_ns.options.noise_suppression =
2831 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002832 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2833 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2834 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2835 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2836 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002837 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002838 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002839 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2840 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2841 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002842 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002843
2844 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002845 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002846 parameters_options_no_agc.options.auto_gain_control =
2847 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002848 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2849 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2850 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2851 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2852 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002853 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002854 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2855 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2856 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002857 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858
solenberg76377c52017-02-21 00:54:31 -08002859 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2863 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002864 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002865
solenberg76377c52017-02-21 00:54:31 -08002866 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2867 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2868 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002871 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002872
solenberg76377c52017-02-21 00:54:31 -08002873 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002878 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002879
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002880 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2882 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002883 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002884 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002885 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002886 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002887 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002892 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002893 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2894 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2895 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002896 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002897}
2898
wu@webrtc.orgde305012013-10-31 15:40:38 +00002899// This test verifies DSCP settings are properly applied on voice media channel.
2900TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002901 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002902 cricket::FakeNetworkInterface network_interface;
2903 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002904 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002905
solenberg059fb442016-10-26 05:12:24 -07002906 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
2907 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
2908
solenbergbc37fc82016-04-04 09:54:44 -07002909 channel.reset(
2910 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002911 channel->SetInterface(&network_interface);
2912 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2913 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2914
2915 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002916 channel.reset(
2917 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002918 channel->SetInterface(&network_interface);
2919 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2920
2921 // Verify that setting the option to false resets the
2922 // DiffServCodePoint.
2923 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002924 channel.reset(
2925 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002926 channel->SetInterface(&network_interface);
2927 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2928 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2929
2930 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002931}
2932
solenberg1ac56142015-10-13 03:58:19 -07002933TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002934 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002935 cricket::WebRtcVoiceMediaChannel* media_channel =
2936 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002937 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002938 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002939 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002940 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2941 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2942 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002943 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002944 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945}
2946
solenberg1ac56142015-10-13 03:58:19 -07002947TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002948 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002950 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2951 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2952 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002953 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002954 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002955 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2956 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002957 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002958 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002959 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002960 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961}
2962
solenberg4bac9c52015-10-09 02:32:53 -07002963TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002964 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002965 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002966 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002967 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002969 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2970 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2971 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002972}
2973
solenberg2100c0b2017-03-01 11:29:29 -08002974TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002975 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002976
2977 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002978 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002979 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2980
2981 // Should remember the volume "2" which will be set on new unsignaled streams,
2982 // and also set the gain to 2 on existing unsignaled streams.
2983 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2984 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2985
2986 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2987 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2988 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2989 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2990 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2991 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2992
2993 // Setting gain with SSRC=0 should affect all unsignaled streams.
2994 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002995 if (kMaxUnsignaledRecvStreams > 1) {
2996 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
2997 }
solenberg2100c0b2017-03-01 11:29:29 -08002998 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
2999
3000 // Setting gain on an individual stream affects only that.
3001 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003002 if (kMaxUnsignaledRecvStreams > 1) {
3003 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3004 }
solenberg2100c0b2017-03-01 11:29:29 -08003005 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006}
3007
pbos8fc7fa72015-07-15 08:02:58 -07003008TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003009 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003010 const std::string kSyncLabel = "AvSyncLabel";
3011
solenbergff976312016-03-30 23:28:51 -07003012 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003013 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3014 sp.sync_label = kSyncLabel;
3015 // Creating two channels to make sure that sync label is set properly for both
3016 // the default voice channel and following ones.
3017 EXPECT_TRUE(channel_->AddRecvStream(sp));
3018 sp.ssrcs[0] += 1;
3019 EXPECT_TRUE(channel_->AddRecvStream(sp));
3020
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003021 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003022 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003023 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003024 << "SyncGroup should be set based on sync_label";
3025 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003026 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003027 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003028}
3029
solenberg3a941542015-11-16 07:34:50 -08003030// TODO(solenberg): Remove, once recv streams are configured through Call.
3031// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003032TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003033 // Test that setting the header extensions results in the expected state
3034 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003035 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003036 ssrcs.push_back(223);
3037 ssrcs.push_back(224);
3038
solenbergff976312016-03-30 23:28:51 -07003039 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003040 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003041 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003042 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003043 cricket::StreamParams::CreateLegacy(ssrc)));
3044 }
3045
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003046 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003047 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003048 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003049 EXPECT_NE(nullptr, s);
3050 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3051 }
3052
3053 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003054 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003055 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003056 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003057 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003058 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003059 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003060 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003061 EXPECT_NE(nullptr, s);
3062 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003063 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3064 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003065 for (const auto& s_ext : s_exts) {
3066 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003067 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003068 }
3069 }
3070 }
3071 }
3072
3073 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003074 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003075 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003076 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003077 EXPECT_NE(nullptr, s);
3078 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3079 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003080}
3081
3082TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3083 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003084 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003085 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003086 static const unsigned char kRtcp[] = {
3087 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3088 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3091 };
jbaucheec21bd2016-03-20 06:15:43 -07003092 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 cricket::WebRtcVoiceMediaChannel* media_channel =
3096 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003097 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 EXPECT_TRUE(media_channel->AddRecvStream(
3099 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3100
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003101 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003103 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003104 EXPECT_EQ(0, s->received_packets());
3105 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3106 EXPECT_EQ(1, s->received_packets());
3107 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3108 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109}
Minyue2013aec2015-05-13 14:14:42 +02003110
solenberg0a617e22015-10-20 15:49:38 -07003111// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003112// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003113TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003114 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003115 EXPECT_TRUE(AddRecvStream(kSsrcY));
3116 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003117 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003118 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3119 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3120 EXPECT_TRUE(AddRecvStream(kSsrcW));
3121 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003122}
3123
solenberg7602aab2016-11-14 11:30:07 -08003124TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3125 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003126 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003127 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003128 cricket::StreamParams::CreateLegacy(kSsrcY)));
3129 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3130 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3131 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003132 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003133 cricket::StreamParams::CreateLegacy(kSsrcW)));
3134 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3135 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003136}
stefan658910c2015-09-03 05:48:32 -07003137
deadbeef884f5852016-01-15 09:20:04 -08003138TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003139 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003140 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3141 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003142
3143 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003144 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3145 EXPECT_TRUE(AddRecvStream(kSsrcX));
3146 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003147
3148 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003149 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3150 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003151
3152 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003153 channel_->SetRawAudioSink(kSsrcX, nullptr);
3154 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003155}
3156
solenberg2100c0b2017-03-01 11:29:29 -08003157TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003158 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003159 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3160 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003161 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3162 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003163
3164 // Should be able to set a default sink even when no stream exists.
3165 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3166
solenberg2100c0b2017-03-01 11:29:29 -08003167 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3168 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003169 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003170 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003171
3172 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003173 channel_->SetRawAudioSink(kSsrc0, nullptr);
3174 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003175
3176 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003177 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3178 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003179
3180 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003181 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003182 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003183 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3184
3185 // Spawn another unsignaled stream - it should be assigned the default sink
3186 // and the previous unsignaled stream should lose it.
3187 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3188 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3189 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3190 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003191 if (kMaxUnsignaledRecvStreams > 1) {
3192 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3193 }
solenberg2100c0b2017-03-01 11:29:29 -08003194 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3195
3196 // Reset the default sink - the second unsignaled stream should lose it.
3197 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003198 if (kMaxUnsignaledRecvStreams > 1) {
3199 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3200 }
solenberg2100c0b2017-03-01 11:29:29 -08003201 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3202
3203 // Try setting the default sink while two streams exists.
3204 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003205 if (kMaxUnsignaledRecvStreams > 1) {
3206 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3207 }
solenberg2100c0b2017-03-01 11:29:29 -08003208 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3209
3210 // Try setting the sink for the first unsignaled stream using its known SSRC.
3211 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003212 if (kMaxUnsignaledRecvStreams > 1) {
3213 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3214 }
solenberg2100c0b2017-03-01 11:29:29 -08003215 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003216 if (kMaxUnsignaledRecvStreams > 1) {
3217 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3218 }
deadbeef884f5852016-01-15 09:20:04 -08003219}
3220
skvlad7a43d252016-03-22 15:32:27 -07003221// Test that, just like the video channel, the voice channel communicates the
3222// network state to the call.
3223TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003224 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003225
3226 EXPECT_EQ(webrtc::kNetworkUp,
3227 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3228 EXPECT_EQ(webrtc::kNetworkUp,
3229 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3230
3231 channel_->OnReadyToSend(false);
3232 EXPECT_EQ(webrtc::kNetworkDown,
3233 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3234 EXPECT_EQ(webrtc::kNetworkUp,
3235 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3236
3237 channel_->OnReadyToSend(true);
3238 EXPECT_EQ(webrtc::kNetworkUp,
3239 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3240 EXPECT_EQ(webrtc::kNetworkUp,
3241 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3242}
3243
aleloi18e0b672016-10-04 02:45:47 -07003244// Test that playout is still started after changing parameters
3245TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3246 SetupRecvStream();
3247 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003248 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003249
3250 // Changing RTP header extensions will recreate the AudioReceiveStream.
3251 cricket::AudioRecvParameters parameters;
3252 parameters.extensions.push_back(
3253 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3254 channel_->SetRecvParameters(parameters);
3255
solenberg2100c0b2017-03-01 11:29:29 -08003256 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003257}
3258
stefan658910c2015-09-03 05:48:32 -07003259// Tests that the library initializes and shuts down properly.
3260TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003261 // If the VoiceEngine wants to gather available codecs early, that's fine but
3262 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003263 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003264 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3265 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003266 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003267 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003268 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003269 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3270 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003271 EXPECT_TRUE(channel != nullptr);
3272 delete channel;
solenbergff976312016-03-30 23:28:51 -07003273}
stefan658910c2015-09-03 05:48:32 -07003274
solenbergff976312016-03-30 23:28:51 -07003275// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003276TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3277 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3278 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3279 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003280 // Return 100ms just in case this function gets called. If we don't,
3281 // we could enter a tight loop since the mock would return 0.
3282 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003283 {
ossuc54071d2016-08-17 02:45:41 -07003284 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003285 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3286 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003287 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003288 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003289 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003290 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3291 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3292 EXPECT_TRUE(channel != nullptr);
3293 delete channel;
3294 }
stefan658910c2015-09-03 05:48:32 -07003295}
3296
ossu20a4b3f2017-04-27 02:08:52 -07003297// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3298TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003299 // TODO(ossu): Why are the payload types of codecs with non-static payload
3300 // type assignments checked here? It shouldn't really matter.
3301 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003302 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3303 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003304 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003305 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3306 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3307 (clockrate == 0 || codec.clockrate == clockrate);
3308 };
3309 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003310 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003311 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003312 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003313 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003314 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003315 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003316 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003317 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003318 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003319 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003320 EXPECT_EQ(126, codec.id);
3321 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3322 // Remove these checks once both send and receive side assigns payload types
3323 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003324 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003325 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003326 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003327 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003328 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003329 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003330 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003331 EXPECT_EQ(111, codec.id);
3332 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3333 EXPECT_EQ("10", codec.params.find("minptime")->second);
3334 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3335 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003336 }
3337 }
stefan658910c2015-09-03 05:48:32 -07003338}
3339
3340// Tests that VoE supports at least 32 channels
3341TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003342 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003343 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3344 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003345 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003346 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003347 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003348
3349 cricket::VoiceMediaChannel* channels[32];
3350 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003351 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003352 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3353 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003354 if (!channel)
3355 break;
stefan658910c2015-09-03 05:48:32 -07003356 channels[num_channels++] = channel;
3357 }
3358
tfarina5237aaf2015-11-10 23:44:30 -08003359 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003360 EXPECT_EQ(expected, num_channels);
3361
3362 while (num_channels > 0) {
3363 delete channels[--num_channels];
3364 }
stefan658910c2015-09-03 05:48:32 -07003365}
3366
3367// Test that we set our preferred codecs properly.
3368TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003369 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3370 // - Check that our builtin codecs are usable by Channel.
3371 // - The codecs provided by the engine is usable by Channel.
3372 // It does not check that the codecs in the RecvParameters are actually
3373 // what we sent in - though it's probably reasonable to expect so, if
3374 // SetRecvParameters returns true.
3375 // I think it will become clear once audio decoder injection is completed.
3376 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003377 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
3378 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003379 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003380 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003381 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003382 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3383 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003384 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003385 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003386 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003387}
ossu9def8002017-02-09 05:14:32 -08003388
3389TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3390 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003391 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3392 {48000, 2, 16000, 10000, 20000}};
3393 spec1.info.allow_comfort_noise = false;
3394 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003395 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003396 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3397 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003398 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003399 specs.push_back(webrtc::AudioCodecSpec{
3400 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3401 {16000, 1, 13300}});
3402 specs.push_back(
3403 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3404 specs.push_back(
3405 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003406
ossueb1fde42017-05-02 06:46:30 -07003407 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3408 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3409 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003410 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003411 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003412 .WillOnce(Return(specs));
3413
ossueb1fde42017-05-02 06:46:30 -07003414 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
3415 mock_decoder_factory, nullptr);
ossu9def8002017-02-09 05:14:32 -08003416 auto codecs = engine.recv_codecs();
3417 EXPECT_EQ(11, codecs.size());
3418
3419 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3420 // check the actual values safely, to provide better test results.
3421 auto get_codec =
3422 [&codecs](size_t index) -> const cricket::AudioCodec& {
3423 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3424 if (codecs.size() > index)
3425 return codecs[index];
3426 return missing_codec;
3427 };
3428
3429 // Ensure the general codecs are generated first and in order.
3430 for (size_t i = 0; i != specs.size(); ++i) {
3431 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3432 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3433 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3434 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3435 }
3436
3437 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003438 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003439 auto find_codec =
3440 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3441 for (size_t i = 0; i != codecs.size(); ++i) {
3442 const cricket::AudioCodec& codec = codecs[i];
3443 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3444 codec.clockrate == format.clockrate_hz &&
3445 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003446 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003447 }
3448 }
3449 return -1;
3450 };
3451
3452 // Ensure all supplementary codecs are generated last. Their internal ordering
3453 // is not important.
3454 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3455 const int num_specs = static_cast<int>(specs.size());
3456 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3457 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3458 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3459 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3460 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3461 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3462 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3463}