blob: 31a092caf0f995411052a0e57726cd2c5fbb50c5 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Seth Hampson24722b32017-12-22 09:36:42 -080016#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
19#include "media/base/fakemediaengine.h"
20#include "media/base/fakenetworkinterface.h"
21#include "media/base/fakertp.h"
22#include "media/base/mediaconstants.h"
23#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
peahb1c9d1d2017-07-25 15:45:24 -070037using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070038using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070039using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070040using testing::ReturnPointee;
41using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070042using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000043
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020044namespace {
45
solenberg418b7d32017-06-13 00:38:27 -070046constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070047
deadbeef67cf2c12016-04-13 10:07:16 -070048const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
49const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070050const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070051const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
52const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070053const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
54const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080055const cricket::AudioCodec
56 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
57const cricket::AudioCodec
58 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
59
solenberg2100c0b2017-03-01 11:29:29 -080060const uint32_t kSsrc0 = 0;
61const uint32_t kSsrc1 = 1;
62const uint32_t kSsrcX = 0x99;
63const uint32_t kSsrcY = 0x17;
64const uint32_t kSsrcZ = 0x42;
65const uint32_t kSsrcW = 0x02;
66const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067
solenberg971cab02016-06-14 10:02:41 -070068constexpr int kRtpHistoryMs = 5000;
69
Fredrik Solenberg55900fd2017-11-23 20:22:55 +010070constexpr webrtc::GainControl::Mode kDefaultAgcMode =
71#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
72 webrtc::GainControl::kFixedDigital;
73#else
74 webrtc::GainControl::kAdaptiveAnalog;
75#endif
76
77constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
78 webrtc::NoiseSuppression::kHigh;
79
solenberg9a5f032222017-03-15 06:14:12 -070080void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
81 RTC_DCHECK(adm);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010082
83 // Setup.
Fredrik Solenberg2a877972017-12-15 16:42:15 +010084 EXPECT_CALL(*adm, AddRef()).Times(3);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010085 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +010086 EXPECT_CALL(*adm, RegisterAudioCallback(_)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070087#if defined(WEBRTC_WIN)
88 EXPECT_CALL(*adm, SetPlayoutDevice(
89 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
90 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
91 .WillOnce(Return(0));
92#else
93 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
94#endif // #if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
96 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
97 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +010098#if defined(WEBRTC_WIN)
99 EXPECT_CALL(*adm, SetRecordingDevice(
100 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
101 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
102 .WillOnce(Return(0));
103#else
104 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
105#endif // #if defined(WEBRTC_WIN)
106 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
107 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
108 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700109 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
110 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
111 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100112
113 // Teardown.
114 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
115 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
116 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
117 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100118 EXPECT_CALL(*adm, Release()).Times(3)
119 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700120}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200121} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122
solenbergff976312016-03-30 23:28:51 -0700123// Tests that our stub library "works".
124TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700125 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700126 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700127 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
128 new rtc::RefCountedObject<
129 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700130 webrtc::AudioProcessing::Config apm_config;
131 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
132 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700133 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700134 EXPECT_CALL(*apm, DetachAecDump());
solenbergff976312016-03-30 23:28:51 -0700135 {
ossuc54071d2016-08-17 02:45:41 -0700136 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700137 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100138 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -0700139 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700140 }
solenbergff976312016-03-30 23:28:51 -0700141}
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)
peaha9cc40b2017-06-29 08:32:09 -0700157 : apm_(new rtc::RefCountedObject<
158 StrictMock<webrtc::test::MockAudioProcessing>>()),
159 apm_gc_(*apm_->gain_control()),
160 apm_ec_(*apm_->echo_cancellation()),
161 apm_ns_(*apm_->noise_suppression()),
162 apm_vd_(*apm_->voice_detection()),
163 call_(webrtc::Call::Config(&event_log_)),
skvlad11a9cbf2016-10-07 11:53:05 -0700164 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800165 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700166 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800167 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700168 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
169 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700170 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
peaha9cc40b2017-06-29 08:32:09 -0700171 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800172 // Default Options.
173 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
174 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100175 EXPECT_CALL(apm_ec_, enable_drift_compensation(false)).WillOnce(Return(0));
176 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800177 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100178 EXPECT_CALL(apm_gc_, set_analog_level_limits(0, 255)).WillOnce(Return(0));
179 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800180 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
181 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800182 // Init does not overwrite default AGC config.
183 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
184 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
185 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
solenberg76377c52017-02-21 00:54:31 -0800186 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
187 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700188 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800189 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700190 // factories. Those tests should probably be moved elsewhere.
191 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
192 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100193 engine_.reset(new cricket::WebRtcVoiceEngine(
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100194 &adm_, encoder_factory, decoder_factory, nullptr, apm_));
deadbeefeb02c032017-06-15 08:29:25 -0700195 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200196 send_parameters_.codecs.push_back(kPcmuCodec);
197 recv_parameters_.codecs.push_back(kPcmuCodec);
Fredrik Solenberg55900fd2017-11-23 20:22:55 +0100198
solenberg76377c52017-02-21 00:54:31 -0800199 // Default Options.
200 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 }
solenberg8189b022016-06-14 12:13:00 -0700202
solenbergff976312016-03-30 23:28:51 -0700203 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700204 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700205 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
206 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200207 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000208 }
solenberg8189b022016-06-14 12:13:00 -0700209
solenbergff976312016-03-30 23:28:51 -0700210 bool SetupRecvStream() {
211 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700212 return false;
213 }
solenberg2100c0b2017-03-01 11:29:29 -0800214 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700215 }
solenberg8189b022016-06-14 12:13:00 -0700216
solenbergff976312016-03-30 23:28:51 -0700217 bool SetupSendStream() {
218 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000219 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 }
solenberg2100c0b2017-03-01 11:29:29 -0800221 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800222 return false;
223 }
peaha9cc40b2017-06-29 08:32:09 -0700224 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800225 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 }
solenberg8189b022016-06-14 12:13:00 -0700227
228 bool AddRecvStream(uint32_t ssrc) {
229 EXPECT_TRUE(channel_);
230 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
231 }
232
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000233 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700234 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700235 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800236 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
237 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700238 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800239 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700243 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000244 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000245 }
solenberg8189b022016-06-14 12:13:00 -0700246
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200247 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 }
250
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100251 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
252 const auto* send_stream = call_.GetAudioSendStream(ssrc);
253 EXPECT_TRUE(send_stream);
254 return *send_stream;
255 }
256
deadbeef884f5852016-01-15 09:20:04 -0800257 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
258 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
259 EXPECT_TRUE(recv_stream);
260 return *recv_stream;
261 }
262
solenberg3a941542015-11-16 07:34:50 -0800263 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800264 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800265 }
266
solenberg7add0582015-11-20 09:59:34 -0800267 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800268 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800269 }
270
solenberg059fb442016-10-26 05:12:24 -0700271 void SetSend(bool enable) {
272 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700273 if (enable) {
274 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
275 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
276 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700277 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700278 }
solenberg059fb442016-10-26 05:12:24 -0700279 channel_->SetSend(enable);
280 }
281
282 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700283 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700284 ASSERT_TRUE(channel_);
285 EXPECT_TRUE(channel_->SetSendParameters(params));
286 }
287
minyue6b825df2016-10-31 04:08:32 -0700288 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
289 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700290 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700291 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700292 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700293 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700294 }
295 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700296 }
297
solenbergffbbcac2016-11-17 05:25:37 -0800298 void TestInsertDtmf(uint32_t ssrc, bool caller,
299 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700300 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000301 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700302 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000303 // send stream.
304 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800305 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000307
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700309 SetSendParameters(send_parameters_);
310 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800312 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800313 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700314 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316
317 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700318 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800319 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800321 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000322 }
323
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800325 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100327 // Test send.
328 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800329 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100330 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800331 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800332 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800333 EXPECT_EQ(codec.id, telephone_event.payload_type);
334 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100335 EXPECT_EQ(2, telephone_event.event_code);
336 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 }
338
339 // Test that send bandwidth is set correctly.
340 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000341 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
342 // |expected_result| is the expected result from SetMaxSendBandwidth().
343 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700344 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
345 int max_bitrate,
346 bool expected_result,
347 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200348 cricket::AudioSendParameters parameters;
349 parameters.codecs.push_back(codec);
350 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700351 if (expected_result) {
352 SetSendParameters(parameters);
353 } else {
354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
355 }
solenberg2100c0b2017-03-01 11:29:29 -0800356 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357 }
358
skvlade0d46372016-04-07 22:59:22 -0700359 // Sets the per-stream maximum bitrate limit for the specified SSRC.
360 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700361 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700362 EXPECT_EQ(1UL, parameters.encodings.size());
363
Oskar Sundbom78807582017-11-16 11:09:55 +0100364 parameters.encodings[0].max_bitrate_bps = bitrate;
Zach Steinba37b4b2018-01-23 15:02:36 -0800365 return channel_->SetRtpSendParameters(ssrc, parameters).ok();
skvlade0d46372016-04-07 22:59:22 -0700366 }
367
solenberg059fb442016-10-26 05:12:24 -0700368 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700369 cricket::AudioSendParameters send_parameters;
370 send_parameters.codecs.push_back(codec);
371 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700372 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700373 }
374
ossu20a4b3f2017-04-27 02:08:52 -0700375 void CheckSendCodecBitrate(int32_t ssrc,
376 const char expected_name[],
377 int expected_bitrate) {
378 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
379 EXPECT_EQ(expected_name, spec->format.name);
380 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700381 }
382
ossu20a4b3f2017-04-27 02:08:52 -0700383 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
384 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700385 }
386
minyue6b825df2016-10-31 04:08:32 -0700387 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
388 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
389 }
390
skvlade0d46372016-04-07 22:59:22 -0700391 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
392 int global_max,
393 int stream_max,
394 bool expected_result,
395 int expected_codec_bitrate) {
396 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800397 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700398
399 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700400 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800401 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700402
403 // Verify that reading back the parameters gives results
404 // consistent with the Set() result.
405 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800406 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700407 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
408 EXPECT_EQ(expected_result ? stream_max : -1,
409 resulting_parameters.encodings[0].max_bitrate_bps);
410
411 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800412 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700413 }
414
stefan13f1a0a2016-11-30 07:22:58 -0800415 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
416 int expected_min_bitrate_bps,
417 const char* start_bitrate_kbps,
418 int expected_start_bitrate_bps,
419 const char* max_bitrate_kbps,
420 int expected_max_bitrate_bps) {
421 EXPECT_TRUE(SetupSendStream());
422 auto& codecs = send_parameters_.codecs;
423 codecs.clear();
424 codecs.push_back(kOpusCodec);
425 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
426 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
427 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
428 SetSendParameters(send_parameters_);
429
430 EXPECT_EQ(expected_min_bitrate_bps,
431 call_.GetConfig().bitrate_config.min_bitrate_bps);
432 EXPECT_EQ(expected_start_bitrate_bps,
433 call_.GetConfig().bitrate_config.start_bitrate_bps);
434 EXPECT_EQ(expected_max_bitrate_bps,
435 call_.GetConfig().bitrate_config.max_bitrate_bps);
436 }
437
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000438 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700439 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000440
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000441 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800442 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000443
444 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700445 send_parameters_.extensions.push_back(
446 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700447 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800448 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200451 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700452 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800453 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000454
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000455 // Ensure extension is set properly.
456 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700457 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700458 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800459 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
460 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
461 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
solenberg7add0582015-11-20 09:59:34 -0800463 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800465 cricket::StreamParams::CreateLegacy(kSsrcY)));
466 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
467 call_.GetAudioSendStream(kSsrcY));
468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000471
472 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200473 send_parameters_.codecs.push_back(kPcmuCodec);
474 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700475 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800476 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
477 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000478 }
479
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000480 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700481 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000483 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485
486 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700487 recv_parameters_.extensions.push_back(
488 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800489 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000492 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800493 recv_parameters_.extensions.clear();
494 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000497 // Ensure extension is set properly.
498 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700499 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800500 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
502 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
503 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
solenberg7add0582015-11-20 09:59:34 -0800505 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800506 EXPECT_TRUE(AddRecvStream(kSsrcY));
507 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
508 call_.GetAudioReceiveStream(kSsrcY));
509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000512
513 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800514 recv_parameters_.extensions.clear();
515 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800516 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
517 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000518 }
519
solenberg85a04962015-10-27 03:35:21 -0700520 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
521 webrtc::AudioSendStream::Stats stats;
522 stats.local_ssrc = 12;
523 stats.bytes_sent = 345;
524 stats.packets_sent = 678;
525 stats.packets_lost = 9012;
526 stats.fraction_lost = 34.56f;
527 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100528 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700529 stats.ext_seqnum = 789;
530 stats.jitter_ms = 12;
531 stats.rtt_ms = 345;
532 stats.audio_level = 678;
Ivo Creusen56d46092017-11-24 17:29:59 +0100533 stats.apm_statistics.delay_median_ms = 234;
534 stats.apm_statistics.delay_standard_deviation_ms = 567;
535 stats.apm_statistics.echo_return_loss = 890;
536 stats.apm_statistics.echo_return_loss_enhancement = 1234;
537 stats.apm_statistics.residual_echo_likelihood = 0.432f;
538 stats.apm_statistics.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100539 stats.ana_statistics.bitrate_action_counter = 321;
540 stats.ana_statistics.channel_action_counter = 432;
541 stats.ana_statistics.dtx_action_counter = 543;
542 stats.ana_statistics.fec_action_counter = 654;
543 stats.ana_statistics.frame_length_increase_counter = 765;
544 stats.ana_statistics.frame_length_decrease_counter = 876;
545 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700546 stats.typing_noise_detected = true;
547 return stats;
548 }
549 void SetAudioSendStreamStats() {
550 for (auto* s : call_.GetAudioSendStreams()) {
551 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200552 }
solenberg85a04962015-10-27 03:35:21 -0700553 }
solenberg566ef242015-11-06 15:34:49 -0800554 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
555 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700556 const auto stats = GetAudioSendStreamStats();
557 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
558 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
559 EXPECT_EQ(info.packets_sent, stats.packets_sent);
560 EXPECT_EQ(info.packets_lost, stats.packets_lost);
561 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
562 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800563 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700564 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
565 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
566 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
567 EXPECT_EQ(info.audio_level, stats.audio_level);
Ivo Creusen56d46092017-11-24 17:29:59 +0100568 EXPECT_EQ(info.apm_statistics.delay_median_ms,
569 stats.apm_statistics.delay_median_ms);
570 EXPECT_EQ(info.apm_statistics.delay_standard_deviation_ms,
571 stats.apm_statistics.delay_standard_deviation_ms);
572 EXPECT_EQ(info.apm_statistics.echo_return_loss,
573 stats.apm_statistics.echo_return_loss);
574 EXPECT_EQ(info.apm_statistics.echo_return_loss_enhancement,
575 stats.apm_statistics.echo_return_loss_enhancement);
576 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood,
577 stats.apm_statistics.residual_echo_likelihood);
578 EXPECT_EQ(info.apm_statistics.residual_echo_likelihood_recent_max,
579 stats.apm_statistics.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700580 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
581 stats.ana_statistics.bitrate_action_counter);
582 EXPECT_EQ(info.ana_statistics.channel_action_counter,
583 stats.ana_statistics.channel_action_counter);
584 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
585 stats.ana_statistics.dtx_action_counter);
586 EXPECT_EQ(info.ana_statistics.fec_action_counter,
587 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700588 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
589 stats.ana_statistics.frame_length_increase_counter);
590 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
591 stats.ana_statistics.frame_length_decrease_counter);
592 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
593 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800594 EXPECT_EQ(info.typing_noise_detected,
595 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700596 }
597
598 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
599 webrtc::AudioReceiveStream::Stats stats;
600 stats.remote_ssrc = 123;
601 stats.bytes_rcvd = 456;
602 stats.packets_rcvd = 768;
603 stats.packets_lost = 101;
604 stats.fraction_lost = 23.45f;
605 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100606 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700607 stats.ext_seqnum = 678;
608 stats.jitter_ms = 901;
609 stats.jitter_buffer_ms = 234;
610 stats.jitter_buffer_preferred_ms = 567;
611 stats.delay_estimate_ms = 890;
612 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700613 stats.total_samples_received = 5678901;
614 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200615 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200616 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700617 stats.expand_rate = 5.67f;
618 stats.speech_expand_rate = 8.90f;
619 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200620 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700621 stats.accelerate_rate = 4.56f;
622 stats.preemptive_expand_rate = 7.89f;
623 stats.decoding_calls_to_silence_generator = 12;
624 stats.decoding_calls_to_neteq = 345;
625 stats.decoding_normal = 67890;
626 stats.decoding_plc = 1234;
627 stats.decoding_cng = 5678;
628 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700629 stats.decoding_muted_output = 3456;
630 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200631 return stats;
632 }
633 void SetAudioReceiveStreamStats() {
634 for (auto* s : call_.GetAudioReceiveStreams()) {
635 s->SetStats(GetAudioReceiveStreamStats());
636 }
637 }
638 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700639 const auto stats = GetAudioReceiveStreamStats();
640 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
641 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
642 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
643 EXPECT_EQ(info.packets_lost, stats.packets_lost);
644 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
645 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800646 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
648 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
649 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200650 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700651 stats.jitter_buffer_preferred_ms);
652 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
653 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700654 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
655 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200656 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200657 EXPECT_EQ(info.jitter_buffer_delay_seconds,
658 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700659 EXPECT_EQ(info.expand_rate, stats.expand_rate);
660 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
661 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200662 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700663 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
664 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200665 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700666 stats.decoding_calls_to_silence_generator);
667 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
668 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
669 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
670 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
671 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700672 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200674 }
hbos1acfbd22016-11-17 23:43:29 -0800675 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
676 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
677 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
678 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
679 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
680 codec.ToCodecParameters());
681 }
682 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
683 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
684 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
685 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
686 codec.ToCodecParameters());
687 }
688 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200689
peah8271d042016-11-22 07:24:52 -0800690 bool IsHighPassFilterEnabled() {
691 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
692 }
693
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700695 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700696 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800697 webrtc::test::MockGainControl& apm_gc_;
698 webrtc::test::MockEchoCancellation& apm_ec_;
699 webrtc::test::MockNoiseSuppression& apm_ns_;
700 webrtc::test::MockVoiceDetection& apm_vd_;
skvlad11a9cbf2016-10-07 11:53:05 -0700701 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200702 cricket::FakeCall call_;
solenbergbc37fc82016-04-04 09:54:44 -0700703 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700704 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200705 cricket::AudioSendParameters send_parameters_;
706 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800707 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700708 webrtc::AudioProcessing::Config apm_config_;
709
stefanba4c0e42016-02-04 04:12:24 -0800710 private:
711 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712};
713
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714// Tests that we can create and destroy a channel.
715TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700716 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717}
718
solenberg31fec402016-05-06 02:13:12 -0700719// Test that we can add a send stream and that it has the correct defaults.
720TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
721 EXPECT_TRUE(SetupChannel());
722 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800723 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
724 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
725 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700726 EXPECT_EQ("", config.rtp.c_name);
727 EXPECT_EQ(0u, config.rtp.extensions.size());
728 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
729 config.send_transport);
730}
731
732// Test that we can add a receive stream and that it has the correct defaults.
733TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
734 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800735 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700736 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800737 GetRecvStreamConfig(kSsrcX);
738 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700739 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
740 EXPECT_FALSE(config.rtp.transport_cc);
741 EXPECT_EQ(0u, config.rtp.extensions.size());
742 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
743 config.rtcp_send_transport);
744 EXPECT_EQ("", config.sync_group);
745}
746
stefanba4c0e42016-02-04 04:12:24 -0800747TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700748 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800749 bool opus_found = false;
750 for (cricket::AudioCodec codec : codecs) {
751 if (codec.name == "opus") {
752 EXPECT_TRUE(HasTransportCc(codec));
753 opus_found = true;
754 }
755 }
756 EXPECT_TRUE(opus_found);
757}
758
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759// Test that we set our inbound codecs properly, including changing PT.
760TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700761 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200762 cricket::AudioRecvParameters parameters;
763 parameters.codecs.push_back(kIsacCodec);
764 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800765 parameters.codecs.push_back(kTelephoneEventCodec1);
766 parameters.codecs.push_back(kTelephoneEventCodec2);
767 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200768 parameters.codecs[2].id = 126;
769 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800770 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700771 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
772 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
773 {{0, {"PCMU", 8000, 1}},
774 {106, {"ISAC", 16000, 1}},
775 {126, {"telephone-event", 8000, 1}},
776 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777}
778
779// Test that we fail to set an unknown inbound codec.
780TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700781 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200782 cricket::AudioRecvParameters parameters;
783 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700784 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200785 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
788// Test that we fail if we have duplicate types in the inbound list.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
793 parameters.codecs.push_back(kCn16000Codec);
794 parameters.codecs[1].id = kIsacCodec.id;
795 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796}
797
798// Test that we can decode OPUS without stereo parameters.
799TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700800 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200801 cricket::AudioRecvParameters parameters;
802 parameters.codecs.push_back(kIsacCodec);
803 parameters.codecs.push_back(kPcmuCodec);
804 parameters.codecs.push_back(kOpusCodec);
805 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800806 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700807 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
808 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
809 {{0, {"PCMU", 8000, 1}},
810 {103, {"ISAC", 16000, 1}},
811 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that we can decode OPUS with stereo = 0.
815TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700816 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200817 cricket::AudioRecvParameters parameters;
818 parameters.codecs.push_back(kIsacCodec);
819 parameters.codecs.push_back(kPcmuCodec);
820 parameters.codecs.push_back(kOpusCodec);
821 parameters.codecs[2].params["stereo"] = "0";
822 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800823 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700824 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
825 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
826 {{0, {"PCMU", 8000, 1}},
827 {103, {"ISAC", 16000, 1}},
828 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829}
830
831// Test that we can decode OPUS with stereo = 1.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
837 parameters.codecs.push_back(kOpusCodec);
838 parameters.codecs[2].params["stereo"] = "1";
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800840 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700841 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
842 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
843 {{0, {"PCMU", 8000, 1}},
844 {103, {"ISAC", 16000, 1}},
845 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846}
847
848// Test that changes to recv codecs are applied to all streams.
849TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700850 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200851 cricket::AudioRecvParameters parameters;
852 parameters.codecs.push_back(kIsacCodec);
853 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800854 parameters.codecs.push_back(kTelephoneEventCodec1);
855 parameters.codecs.push_back(kTelephoneEventCodec2);
856 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200857 parameters.codecs[2].id = 126;
858 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700859 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
860 EXPECT_TRUE(AddRecvStream(ssrc));
861 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
862 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
863 {{0, {"PCMU", 8000, 1}},
864 {106, {"ISAC", 16000, 1}},
865 {126, {"telephone-event", 8000, 1}},
866 {107, {"telephone-event", 32000, 1}}})));
867 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868}
869
870TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700871 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200872 cricket::AudioRecvParameters parameters;
873 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800874 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876
solenberg2100c0b2017-03-01 11:29:29 -0800877 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800878 ASSERT_EQ(1, dm.count(106));
879 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882// Test that we can apply the same set of codecs again while playing.
883TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
887 parameters.codecs.push_back(kCn16000Codec);
888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700889 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891
deadbeefcb383672017-04-26 16:28:42 -0700892 // Remapping a payload type to a different codec should fail.
893 parameters.codecs[0] = kOpusCodec;
894 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200895 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800896 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897}
898
899// Test that we can add a codec while playing.
900TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700901 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 cricket::AudioRecvParameters parameters;
903 parameters.codecs.push_back(kIsacCodec);
904 parameters.codecs.push_back(kCn16000Codec);
905 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700906 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200908 parameters.codecs.push_back(kOpusCodec);
909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911}
912
deadbeefcb383672017-04-26 16:28:42 -0700913// Test that we accept adding the same codec with a different payload type.
914// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
915TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
916 EXPECT_TRUE(SetupRecvStream());
917 cricket::AudioRecvParameters parameters;
918 parameters.codecs.push_back(kIsacCodec);
919 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
920
921 ++parameters.codecs[0].id;
922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
923}
924
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700926 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000928 // Test that when autobw is enabled, bitrate is kept as the default
929 // value. autobw is enabled for the following tests because the target
930 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931
932 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700933 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
935 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700936 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937
ossu20a4b3f2017-04-27 02:08:52 -0700938 // opus, default bitrate == 32000 in mono.
939 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940}
941
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000942TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700943 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700946 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
947 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700948 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700951 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
952 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
953 // Rates above the max (510000) should be capped.
954 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955}
956
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000957TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700958 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000959
960 // Test that we can only set a maximum bitrate for a fixed-rate codec
961 // if it's bigger than the fixed rate.
962
963 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
965 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
966 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
967 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
968 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
969 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
970 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971}
972
973TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700974 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 const int kDesiredBitrate = 128000;
976 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700977 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200978 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700979 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000980
981 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800982 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000983
solenberg2100c0b2017-03-01 11:29:29 -0800984 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000985}
986
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987// Test that bitrate cannot be set for CBR codecs.
988// Bitrate is ignored if it is higher than the fixed bitrate.
989// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700991 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992
993 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700994 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800995 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200996
997 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700998 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800999 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001000
1001 send_parameters_.max_bandwidth_bps = 128;
1002 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001003 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004}
1005
skvlade0d46372016-04-07 22:59:22 -07001006// Test that the per-stream bitrate limit and the global
1007// bitrate limit both apply.
1008TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1009 EXPECT_TRUE(SetupSendStream());
1010
ossu20a4b3f2017-04-27 02:08:52 -07001011 // opus, default bitrate == 32000.
1012 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001013 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1014 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1015 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1016
1017 // CBR codecs allow both maximums to exceed the bitrate.
1018 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1019 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1020 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1021 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1022
1023 // CBR codecs don't allow per stream maximums to be too low.
1024 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1025 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1026}
1027
1028// Test that an attempt to set RtpParameters for a stream that does not exist
1029// fails.
1030TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1031 EXPECT_TRUE(SetupChannel());
1032 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001033 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001034 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1035
1036 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001037 EXPECT_FALSE(
1038 channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001039}
1040
1041TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001042 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001043 // This test verifies that setting RtpParameters succeeds only if
1044 // the structure contains exactly one encoding.
1045 // TODO(skvlad): Update this test when we start supporting setting parameters
1046 // for each encoding individually.
1047
1048 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001049 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001050 // Two or more encodings should result in failure.
1051 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08001052 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001053 // Zero encodings should also fail.
1054 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08001055 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08001056}
1057
1058// Changing the SSRC through RtpParameters is not allowed.
1059TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1060 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001061 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001062 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
skvlade0d46372016-04-07 22:59:22 -07001064}
1065
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001066// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001067// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001068TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1069 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001070 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001072 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001073 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074 ASSERT_EQ(1u, parameters.encodings.size());
1075 ASSERT_TRUE(parameters.encodings[0].active);
1076 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08001077 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001078 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079
1080 // Now change it back to active and verify we resume sending.
Seth Hampson24722b32017-12-22 09:36:42 -08001081 // This should occur even when other parameters are updated.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082 parameters.encodings[0].active = true;
Seth Hampson24722b32017-12-22 09:36:42 -08001083 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(6000);
Zach Steinba37b4b2018-01-23 15:02:36 -08001084 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001086}
1087
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001088// Test that SetRtpSendParameters configures the correct encoding channel for
1089// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001090TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1091 SetupForMultiSendStream();
1092 // Create send streams.
1093 for (uint32_t ssrc : kSsrcs4) {
1094 EXPECT_TRUE(
1095 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1096 }
1097 // Configure one stream to be limited by the stream config, another to be
1098 // limited by the global max, and the third one with no per-stream limit
1099 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001100 SetGlobalMaxBitrate(kOpusCodec, 32000);
1101 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1102 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001103 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1104
ossu20a4b3f2017-04-27 02:08:52 -07001105 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1106 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1107 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001108
1109 // Remove the global cap; the streams should switch to their respective
1110 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001111 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001112 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1113 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1114 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001115}
1116
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001117// Test that GetRtpSendParameters returns the currently configured codecs.
1118TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001119 EXPECT_TRUE(SetupSendStream());
1120 cricket::AudioSendParameters parameters;
1121 parameters.codecs.push_back(kIsacCodec);
1122 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001123 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001124
solenberg2100c0b2017-03-01 11:29:29 -08001125 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001126 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1128 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129}
1130
deadbeefcb443432016-12-12 11:12:36 -08001131// Test that GetRtpSendParameters returns an SSRC.
1132TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1133 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001134 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001135 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001136 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001137}
1138
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001139// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001140TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001141 EXPECT_TRUE(SetupSendStream());
1142 cricket::AudioSendParameters parameters;
1143 parameters.codecs.push_back(kIsacCodec);
1144 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001145 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001146
solenberg2100c0b2017-03-01 11:29:29 -08001147 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148
1149 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08001150 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001151
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001152 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001153 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1154 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001155}
1156
minyuececec102017-03-27 13:04:25 -07001157// Test that max_bitrate_bps in send stream config gets updated correctly when
1158// SetRtpSendParameters is called.
1159TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1160 webrtc::test::ScopedFieldTrials override_field_trials(
1161 "WebRTC-Audio-SendSideBwe/Enabled/");
1162 EXPECT_TRUE(SetupSendStream());
1163 cricket::AudioSendParameters send_parameters;
1164 send_parameters.codecs.push_back(kOpusCodec);
1165 SetSendParameters(send_parameters);
1166
1167 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1168 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1169 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1170
1171 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001172 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08001173 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07001174
1175 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1176 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1177}
1178
Seth Hampson24722b32017-12-22 09:36:42 -08001179// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
1180// a value <= 0, setting the parameters returns false.
1181TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterInvalidBitratePriority) {
1182 EXPECT_TRUE(SetupSendStream());
1183 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1184 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1185 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1186 rtp_parameters.encodings[0].bitrate_priority);
1187
1188 rtp_parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001189 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001190 rtp_parameters.encodings[0].bitrate_priority = -1.0;
Zach Steinba37b4b2018-01-23 15:02:36 -08001191 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001192}
1193
1194// Test that the bitrate_priority in the send stream config gets updated when
1195// SetRtpSendParameters is set for the VoiceMediaChannel.
1196TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesBitratePriority) {
1197 EXPECT_TRUE(SetupSendStream());
1198 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1199
1200 EXPECT_EQ(1UL, rtp_parameters.encodings.size());
1201 EXPECT_EQ(webrtc::kDefaultBitratePriority,
1202 rtp_parameters.encodings[0].bitrate_priority);
1203 double new_bitrate_priority = 2.0;
1204 rtp_parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08001205 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08001206
1207 // The priority should get set for both the audio channel's rtp parameters
1208 // and the audio send stream's audio config.
1209 EXPECT_EQ(
1210 new_bitrate_priority,
1211 channel_->GetRtpSendParameters(kSsrcX).encodings[0].bitrate_priority);
1212 EXPECT_EQ(new_bitrate_priority, GetSendStreamConfig(kSsrcX).bitrate_priority);
1213}
1214
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001215// Test that GetRtpReceiveParameters returns the currently configured codecs.
1216TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1217 EXPECT_TRUE(SetupRecvStream());
1218 cricket::AudioRecvParameters parameters;
1219 parameters.codecs.push_back(kIsacCodec);
1220 parameters.codecs.push_back(kPcmuCodec);
1221 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1222
1223 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001224 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1226 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1227 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1228}
1229
deadbeefcb443432016-12-12 11:12:36 -08001230// Test that GetRtpReceiveParameters returns an SSRC.
1231TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1232 EXPECT_TRUE(SetupRecvStream());
1233 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001234 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001235 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001236 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001237}
1238
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001239// Test that if we set/get parameters multiple times, we get the same results.
1240TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1241 EXPECT_TRUE(SetupRecvStream());
1242 cricket::AudioRecvParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
1245 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1246
1247 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001248 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001249
1250 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001251 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001252
1253 // ... And this shouldn't change the params returned by
1254 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001255 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1256 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001257}
1258
deadbeef3bc15102017-04-20 19:25:07 -07001259// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1260// aren't signaled. It should return an empty "RtpEncodingParameters" when
1261// configured to receive an unsignaled stream and no packets have been received
1262// yet, and start returning the SSRC once a packet has been received.
1263TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1264 ASSERT_TRUE(SetupChannel());
1265 // Call necessary methods to configure receiving a default stream as
1266 // soon as it arrives.
1267 cricket::AudioRecvParameters parameters;
1268 parameters.codecs.push_back(kIsacCodec);
1269 parameters.codecs.push_back(kPcmuCodec);
1270 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1271
1272 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1273 // stream. Should return nothing.
1274 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1275
1276 // Set a sink for an unsignaled stream.
1277 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1278 // Value of "0" means "unsignaled stream".
1279 channel_->SetRawAudioSink(0, std::move(fake_sink));
1280
1281 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1282 // in this method means "unsignaled stream".
1283 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1284 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1285 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1286
1287 // Receive PCMU packet (SSRC=1).
1288 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1289
1290 // The |ssrc| member should still be unset.
1291 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1292 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1293 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1294}
1295
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001296// Test that we apply codecs properly.
1297TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001298 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001299 cricket::AudioSendParameters parameters;
1300 parameters.codecs.push_back(kIsacCodec);
1301 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001302 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001303 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001304 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001305 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001306 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1307 EXPECT_EQ(96, send_codec_spec.payload_type);
1308 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1309 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1310 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001311 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001312 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313}
1314
ossu20a4b3f2017-04-27 02:08:52 -07001315// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1316// AudioSendStream.
1317TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001318 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001319 cricket::AudioSendParameters parameters;
1320 parameters.codecs.push_back(kIsacCodec);
1321 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001322 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001323 parameters.codecs[0].id = 96;
1324 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001325 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001326 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001327 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001328 // Calling SetSendCodec again with same codec which is already set.
1329 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001330 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001331 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001332}
1333
ossu20a4b3f2017-04-27 02:08:52 -07001334// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1335// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001336
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001337// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001339 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 cricket::AudioSendParameters parameters;
1341 parameters.codecs.push_back(kOpusCodec);
1342 parameters.codecs[0].bitrate = 0;
1343 parameters.codecs[0].clockrate = 50000;
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001347// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001349 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 cricket::AudioSendParameters parameters;
1351 parameters.codecs.push_back(kOpusCodec);
1352 parameters.codecs[0].bitrate = 0;
1353 parameters.codecs[0].channels = 0;
1354 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355}
1356
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001357// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].channels = 0;
1364 parameters.codecs[0].params["stereo"] = "1";
1365 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001366}
1367
1368// Test that if channel is 1 for opus and there's no stereo, we fail.
1369TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001370 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 cricket::AudioSendParameters parameters;
1372 parameters.codecs.push_back(kOpusCodec);
1373 parameters.codecs[0].bitrate = 0;
1374 parameters.codecs[0].channels = 1;
1375 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376}
1377
1378// Test that if channel is 1 for opus and stereo=0, we fail.
1379TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001380 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001381 cricket::AudioSendParameters parameters;
1382 parameters.codecs.push_back(kOpusCodec);
1383 parameters.codecs[0].bitrate = 0;
1384 parameters.codecs[0].channels = 1;
1385 parameters.codecs[0].params["stereo"] = "0";
1386 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387}
1388
1389// Test that if channel is 1 for opus and stereo=1, we fail.
1390TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001391 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 cricket::AudioSendParameters parameters;
1393 parameters.codecs.push_back(kOpusCodec);
1394 parameters.codecs[0].bitrate = 0;
1395 parameters.codecs[0].channels = 1;
1396 parameters.codecs[0].params["stereo"] = "1";
1397 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
ossu20a4b3f2017-04-27 02:08:52 -07001400// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001406 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001407 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408}
1409
ossu20a4b3f2017-04-27 02:08:52 -07001410// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001411TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001412 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 cricket::AudioSendParameters parameters;
1414 parameters.codecs.push_back(kOpusCodec);
1415 parameters.codecs[0].bitrate = 0;
1416 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001418 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419}
1420
ossu20a4b3f2017-04-27 02:08:52 -07001421// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001422TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001423 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 cricket::AudioSendParameters parameters;
1425 parameters.codecs.push_back(kOpusCodec);
1426 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001427 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001430 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001431
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001433 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001434 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001435}
1436
ossu20a4b3f2017-04-27 02:08:52 -07001437// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001439 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 cricket::AudioSendParameters parameters;
1441 parameters.codecs.push_back(kOpusCodec);
1442 parameters.codecs[0].bitrate = 0;
1443 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446}
1447
ossu20a4b3f2017-04-27 02:08:52 -07001448// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001450 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 cricket::AudioSendParameters parameters;
1452 parameters.codecs.push_back(kOpusCodec);
1453 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001454 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001456 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001457 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001458
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001461 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001462}
1463
ossu20a4b3f2017-04-27 02:08:52 -07001464// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001466 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 cricket::AudioSendParameters parameters;
1468 parameters.codecs.push_back(kOpusCodec);
1469 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001470 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001471 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1472 EXPECT_EQ(111, spec.payload_type);
1473 EXPECT_EQ(96000, spec.target_bitrate_bps);
1474 EXPECT_EQ("opus", spec.format.name);
1475 EXPECT_EQ(2, spec.format.num_channels);
1476 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477}
1478
ossu20a4b3f2017-04-27 02:08:52 -07001479// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 30000;
1485 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001487 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
ossu20a4b3f2017-04-27 02:08:52 -07001490// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001492 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001493 cricket::AudioSendParameters parameters;
1494 parameters.codecs.push_back(kOpusCodec);
1495 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001497 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498}
1499
ossu20a4b3f2017-04-27 02:08:52 -07001500// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001502 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 cricket::AudioSendParameters parameters;
1504 parameters.codecs.push_back(kOpusCodec);
1505 parameters.codecs[0].bitrate = 30000;
1506 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001508 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001509}
1510
stefan13f1a0a2016-11-30 07:22:58 -08001511TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1512 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1513 200000);
1514}
1515
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1517 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1518}
1519
1520TEST_F(WebRtcVoiceEngineTestFake,
1521 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1522 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1523}
1524
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1526 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1527}
1528
1529TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001530 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001531 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1532 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001533 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001534 SetSendParameters(send_parameters_);
1535 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1536 << "Setting max bitrate should keep previous min bitrate.";
1537 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1538 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001539 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001540}
1541
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001542// Test that we can enable NACK with opus as caller.
1543TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001544 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 cricket::AudioSendParameters parameters;
1546 parameters.codecs.push_back(kOpusCodec);
1547 parameters.codecs[0].AddFeedbackParam(
1548 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1549 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001550 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001551 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553}
1554
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001555// Test that we can enable NACK with opus as callee.
1556TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001557 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 cricket::AudioSendParameters parameters;
1559 parameters.codecs.push_back(kOpusCodec);
1560 parameters.codecs[0].AddFeedbackParam(
1561 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1562 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001563 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001564 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001565 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001566 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001567
1568 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001569 cricket::StreamParams::CreateLegacy(kSsrcX)));
1570 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001571}
1572
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573// Test that we can enable NACK on receive streams.
1574TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001575 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001576 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001577 cricket::AudioSendParameters parameters;
1578 parameters.codecs.push_back(kOpusCodec);
1579 parameters.codecs[0].AddFeedbackParam(
1580 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1581 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1583 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001584 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1586 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587}
1588
1589// Test that we can disable NACK.
1590TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001591 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001592 cricket::AudioSendParameters parameters;
1593 parameters.codecs.push_back(kOpusCodec);
1594 parameters.codecs[0].AddFeedbackParam(
1595 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1596 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001597 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001600 parameters.codecs.clear();
1601 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001603 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
1606// Test that we can disable NACK on receive streams.
1607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001608 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001609 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001610 cricket::AudioSendParameters parameters;
1611 parameters.codecs.push_back(kOpusCodec);
1612 parameters.codecs[0].AddFeedbackParam(
1613 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1614 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001616 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1617 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 parameters.codecs.clear();
1620 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1623 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624}
1625
1626// Test that NACK is enabled on a new receive stream.
1627TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001628 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 cricket::AudioSendParameters parameters;
1630 parameters.codecs.push_back(kIsacCodec);
1631 parameters.codecs.push_back(kCn16000Codec);
1632 parameters.codecs[0].AddFeedbackParam(
1633 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1634 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
solenberg2100c0b2017-03-01 11:29:29 -08001638 EXPECT_TRUE(AddRecvStream(kSsrcY));
1639 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1640 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1641 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642}
1643
stefanba4c0e42016-02-04 04:12:24 -08001644TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001646 cricket::AudioSendParameters send_parameters;
1647 send_parameters.codecs.push_back(kOpusCodec);
1648 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001649 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001650
1651 cricket::AudioRecvParameters recv_parameters;
1652 recv_parameters.codecs.push_back(kIsacCodec);
1653 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_TRUE(AddRecvStream(kSsrcX));
1655 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001656 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001657 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001658
ossudedfd282016-06-14 07:12:39 -07001659 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001662 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001663 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001664}
1665
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001666// Test that we can switch back and forth between Opus and ISAC with CN.
1667TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001668 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001669
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001670 cricket::AudioSendParameters opus_parameters;
1671 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(111, spec.payload_type);
1676 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001677 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::AudioSendParameters isac_parameters;
1680 isac_parameters.codecs.push_back(kIsacCodec);
1681 isac_parameters.codecs.push_back(kCn16000Codec);
1682 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001684 {
ossu20a4b3f2017-04-27 02:08:52 -07001685 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1686 EXPECT_EQ(103, spec.payload_type);
1687 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001688 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001691 {
ossu20a4b3f2017-04-27 02:08:52 -07001692 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1693 EXPECT_EQ(111, spec.payload_type);
1694 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001695 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696}
1697
1698// Test that we handle various ways of specifying bitrate.
1699TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001700 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001701 cricket::AudioSendParameters parameters;
1702 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001704 {
ossu20a4b3f2017-04-27 02:08:52 -07001705 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1706 EXPECT_EQ(103, spec.payload_type);
1707 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1708 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001710
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001713 {
ossu20a4b3f2017-04-27 02:08:52 -07001714 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1715 EXPECT_EQ(103, spec.payload_type);
1716 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1717 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001718 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001719 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001720 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001721 {
ossu20a4b3f2017-04-27 02:08:52 -07001722 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1723 EXPECT_EQ(103, spec.payload_type);
1724 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1725 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001726 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001727
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001728 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001730 {
ossu20a4b3f2017-04-27 02:08:52 -07001731 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1732 EXPECT_EQ(0, spec.payload_type);
1733 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1734 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001735 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001737 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001739 {
ossu20a4b3f2017-04-27 02:08:52 -07001740 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1741 EXPECT_EQ(0, spec.payload_type);
1742 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1743 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001744 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001745
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001746 parameters.codecs[0] = kOpusCodec;
1747 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001749 {
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(111, spec.payload_type);
1752 EXPECT_STREQ("opus", spec.format.name.c_str());
1753 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001754 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755}
1756
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001757// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001759 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 cricket::AudioSendParameters parameters;
1761 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001762}
1763
1764// Test that we can set send codecs even with telephone-event codec as the first
1765// one on the list.
1766TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001767 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001769 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001770 parameters.codecs.push_back(kIsacCodec);
1771 parameters.codecs.push_back(kPcmuCodec);
1772 parameters.codecs[0].id = 98; // DTMF
1773 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001774 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001775 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1776 EXPECT_EQ(96, spec.payload_type);
1777 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Harald Alvestranda1f66612018-02-21 11:24:23 +01001778 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001779 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001780}
1781
Harald Alvestranda1f66612018-02-21 11:24:23 +01001782// Test that CanInsertDtmf() is governed by the send flag
1783TEST_F(WebRtcVoiceEngineTestFake, DTMFControlledBySendFlag) {
1784 EXPECT_TRUE(SetupSendStream());
1785 cricket::AudioSendParameters parameters;
1786 parameters.codecs.push_back(kTelephoneEventCodec1);
1787 parameters.codecs.push_back(kPcmuCodec);
1788 parameters.codecs[0].id = 98; // DTMF
1789 parameters.codecs[1].id = 96;
1790 SetSendParameters(parameters);
1791 EXPECT_FALSE(channel_->CanInsertDtmf());
1792 SetSend(true);
1793 EXPECT_TRUE(channel_->CanInsertDtmf());
1794 SetSend(false);
1795 EXPECT_FALSE(channel_->CanInsertDtmf());
1796}
1797
solenberg31642aa2016-03-14 08:00:37 -07001798// Test that payload type range is limited for telephone-event codec.
1799TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001800 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001801 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001802 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001803 parameters.codecs.push_back(kIsacCodec);
1804 parameters.codecs[0].id = 0; // DTMF
1805 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001807 SetSend(true);
solenberg31642aa2016-03-14 08:00:37 -07001808 EXPECT_TRUE(channel_->CanInsertDtmf());
1809 parameters.codecs[0].id = 128; // DTMF
1810 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1811 EXPECT_FALSE(channel_->CanInsertDtmf());
1812 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001813 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001814 EXPECT_TRUE(channel_->CanInsertDtmf());
1815 parameters.codecs[0].id = -1; // DTMF
1816 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1817 EXPECT_FALSE(channel_->CanInsertDtmf());
1818}
1819
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001820// Test that we can set send codecs even with CN codec as the first
1821// one on the list.
1822TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001823 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 cricket::AudioSendParameters parameters;
1825 parameters.codecs.push_back(kCn16000Codec);
1826 parameters.codecs.push_back(kIsacCodec);
1827 parameters.codecs.push_back(kPcmuCodec);
1828 parameters.codecs[0].id = 98; // wideband CN
1829 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001831 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1832 EXPECT_EQ(96, send_codec_spec.payload_type);
1833 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001834 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835}
1836
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001837// Test that we set VAD and DTMF types correctly as caller.
1838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 cricket::AudioSendParameters parameters;
1841 parameters.codecs.push_back(kIsacCodec);
1842 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001843 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 parameters.codecs.push_back(kCn16000Codec);
1845 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001846 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs[0].id = 96;
1848 parameters.codecs[2].id = 97; // wideband CN
1849 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001850 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001851 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1852 EXPECT_EQ(96, send_codec_spec.payload_type);
1853 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1854 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001855 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001856 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001857 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001858}
1859
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001860// Test that we set VAD and DTMF types correctly as callee.
1861TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001863 cricket::AudioSendParameters parameters;
1864 parameters.codecs.push_back(kIsacCodec);
1865 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001866 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001867 parameters.codecs.push_back(kCn16000Codec);
1868 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001869 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 parameters.codecs[0].id = 96;
1871 parameters.codecs[2].id = 97; // wideband CN
1872 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001874 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001875 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001876
ossu20a4b3f2017-04-27 02:08:52 -07001877 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1878 EXPECT_EQ(96, send_codec_spec.payload_type);
1879 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1880 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001881 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001882 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001883 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001884}
1885
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001886// Test that we only apply VAD if we have a CN codec that matches the
1887// send codec clockrate.
1888TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001889 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001891 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 parameters.codecs.push_back(kIsacCodec);
1893 parameters.codecs.push_back(kCn16000Codec);
1894 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001895 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001896 {
ossu20a4b3f2017-04-27 02:08:52 -07001897 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1898 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1899 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001900 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001901 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001902 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001903 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001904 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001905 {
ossu20a4b3f2017-04-27 02:08:52 -07001906 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1907 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001908 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001909 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001911 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001913 {
ossu20a4b3f2017-04-27 02:08:52 -07001914 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1915 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1916 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001917 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001918 }
Brave Yao5225dd82015-03-26 07:39:19 +08001919 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001920 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001921 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001922 {
ossu20a4b3f2017-04-27 02:08:52 -07001923 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1924 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001925 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001926 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001927}
1928
1929// Test that we perform case-insensitive matching of codec names.
1930TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001931 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 cricket::AudioSendParameters parameters;
1933 parameters.codecs.push_back(kIsacCodec);
1934 parameters.codecs.push_back(kPcmuCodec);
1935 parameters.codecs.push_back(kCn16000Codec);
1936 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001937 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001938 parameters.codecs[0].name = "iSaC";
1939 parameters.codecs[0].id = 96;
1940 parameters.codecs[2].id = 97; // wideband CN
1941 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001943 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1944 EXPECT_EQ(96, send_codec_spec.payload_type);
1945 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1946 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001947 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Harald Alvestranda1f66612018-02-21 11:24:23 +01001948 SetSend(true);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001949 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001950}
1951
stefanba4c0e42016-02-04 04:12:24 -08001952class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1953 public:
1954 WebRtcVoiceEngineWithSendSideBweTest()
1955 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1956};
1957
1958TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1959 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001960 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001961 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001962 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1963 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1964 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001965 extension.id);
1966 return;
1967 }
1968 }
1969 FAIL() << "Transport sequence number extension not in header-extension list.";
1970}
1971
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001972// Test support for audio level header extension.
1973TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001974 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001975}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001976TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001977 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001978}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001979
solenbergd4adce42016-11-17 06:26:52 -08001980// Test support for transport sequence number header extension.
1981TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1982 TestSetSendRtpHeaderExtensions(
1983 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001984}
solenbergd4adce42016-11-17 06:26:52 -08001985TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1986 TestSetRecvRtpHeaderExtensions(
1987 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988}
1989
solenberg1ac56142015-10-13 03:58:19 -07001990// Test that we can create a channel and start sending on it.
1991TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001992 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001993 SetSendParameters(send_parameters_);
1994 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001996 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001998}
1999
2000// Test that a channel will send if and only if it has a source and is enabled
2001// for sending.
2002TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002003 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002004 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002005 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002006 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002007 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2008 SetAudioSend(kSsrcX, true, &fake_source_);
2009 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2010 SetAudioSend(kSsrcX, true, nullptr);
2011 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002012}
2013
solenberg94218532016-06-16 10:53:22 -07002014// Test that a channel is muted/unmuted.
2015TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2016 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002017 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002018 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2019 SetAudioSend(kSsrcX, true, nullptr);
2020 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2021 SetAudioSend(kSsrcX, false, nullptr);
2022 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002023}
2024
solenberg6d6e7c52016-04-13 09:07:30 -07002025// Test that SetSendParameters() does not alter a stream's send state.
2026TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2027 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002028 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002029
2030 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002031 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002032 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002033
2034 // Changing RTP header extensions will recreate the AudioSendStream.
2035 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002036 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002037 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002038 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002039
2040 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002041 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002042 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002043
2044 // Changing RTP header extensions will recreate the AudioSendStream.
2045 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002046 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002047 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002048}
2049
solenberg1ac56142015-10-13 03:58:19 -07002050// Test that we can create a channel and start playing out on it.
2051TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002052 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002053 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002054 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002055 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002056 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002057 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002058}
2059
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060// Test that we can add and remove send streams.
2061TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2062 SetupForMultiSendStream();
2063
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002064 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002065 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002066
solenbergc96df772015-10-21 13:01:53 -07002067 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002069 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002070 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002072 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073 }
tfarina5237aaf2015-11-10 23:44:30 -08002074 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075
solenbergc96df772015-10-21 13:01:53 -07002076 // Delete the send streams.
2077 for (uint32_t ssrc : kSsrcs4) {
2078 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002079 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002080 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002081 }
solenbergc96df772015-10-21 13:01:53 -07002082 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083}
2084
2085// Test SetSendCodecs correctly configure the codecs in all send streams.
2086TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2087 SetupForMultiSendStream();
2088
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002090 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002091 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002092 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002093 }
2094
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002095 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002097 parameters.codecs.push_back(kIsacCodec);
2098 parameters.codecs.push_back(kCn16000Codec);
2099 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002100 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101
2102 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002103 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002104 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2105 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002106 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2107 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2108 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002109 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 }
2111
minyue7a973442016-10-20 03:27:12 -07002112 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002113 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002114 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002115 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002116 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2117 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002118 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2119 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002120 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002121 }
2122}
2123
2124// Test we can SetSend on all send streams correctly.
2125TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2126 SetupForMultiSendStream();
2127
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002128 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002129 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002131 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002132 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002133 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 }
2135
2136 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002137 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002138 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002140 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002141 }
2142
2143 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002144 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002145 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002146 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002147 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148 }
2149}
2150
2151// Test we can set the correct statistics on all send streams.
2152TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2153 SetupForMultiSendStream();
2154
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002155 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002156 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002158 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002159 }
solenberg85a04962015-10-27 03:35:21 -07002160
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002161 // Create a receive stream to check that none of the send streams end up in
2162 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002163 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002164
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002166 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002167 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002168 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002169
solenberg85a04962015-10-27 03:35:21 -07002170 // Check stats for the added streams.
2171 {
2172 cricket::VoiceMediaInfo info;
2173 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002174
solenberg85a04962015-10-27 03:35:21 -07002175 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002176 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002177 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002178 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002179 }
hbos1acfbd22016-11-17 23:43:29 -08002180 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002181
2182 // We have added one receive stream. We should see empty stats.
2183 EXPECT_EQ(info.receivers.size(), 1u);
2184 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002185 }
solenberg1ac56142015-10-13 03:58:19 -07002186
solenberg2100c0b2017-03-01 11:29:29 -08002187 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002188 {
2189 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002190 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002191 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002192 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002193 EXPECT_EQ(0u, info.receivers.size());
2194 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002195
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002196 // Deliver a new packet - a default receive stream should be created and we
2197 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002198 {
2199 cricket::VoiceMediaInfo info;
2200 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2201 SetAudioReceiveStreamStats();
2202 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002203 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002204 EXPECT_EQ(1u, info.receivers.size());
2205 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002206 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002207 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002208}
2209
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002210// Test that we can add and remove receive streams, and do proper send/playout.
2211// We can receive on multiple streams while sending one stream.
2212TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002213 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002214
solenberg1ac56142015-10-13 03:58:19 -07002215 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002216 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002217 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218
solenberg1ac56142015-10-13 03:58:19 -07002219 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002220 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002221 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002222 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002223
solenberg1ac56142015-10-13 03:58:19 -07002224 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002225 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002226
2227 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002228 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2229 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2230 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002231
2232 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002233 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002234 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002235
2236 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002237 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002238 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2239 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002240
aleloi84ef6152016-08-04 05:28:21 -07002241 // Restart playout and make sure recv streams are played out.
2242 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002243 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2244 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002245
aleloi84ef6152016-08-04 05:28:21 -07002246 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002247 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2248 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002249}
2250
wu@webrtc.org97077a32013-10-25 21:18:33 +00002251TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002252 EXPECT_TRUE(SetupSendStream());
Steve Anton606a5972017-12-07 14:31:01 -08002253 EXPECT_CALL(adm_, BuiltInAGCIsAvailable())
2254 .Times(1)
2255 .WillRepeatedly(Return(false));
Steve Anton606a5972017-12-07 14:31:01 -08002256 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(1).WillOnce(Return(0));
2257 EXPECT_CALL(apm_gc_, Enable(true)).Times(1).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002258 send_parameters_.options.tx_agc_target_dbov = 3;
2259 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2260 send_parameters_.options.tx_agc_limiter = true;
2261 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002262 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2263 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2264 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002265 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002266}
2267
minyue6b825df2016-10-31 04:08:32 -07002268TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2269 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002270 send_parameters_.options.audio_network_adaptor = true;
2271 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002272 SetSendParameters(send_parameters_);
2273 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002274 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275}
2276
2277TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2278 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002279 send_parameters_.options.audio_network_adaptor = true;
2280 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002281 SetSendParameters(send_parameters_);
2282 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002283 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002284 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002285 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002286 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002287 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002288}
2289
2290TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2291 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002292 send_parameters_.options.audio_network_adaptor = true;
2293 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002294 SetSendParameters(send_parameters_);
2295 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002296 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002297 const int initial_num = call_.GetNumCreatedSendStreams();
2298 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002299 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002300 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2301 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002302 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002303 // AudioSendStream not expected to be recreated.
2304 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2305 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002306 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002307}
2308
michaelt6672b262017-01-11 10:17:59 -08002309class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2310 : public WebRtcVoiceEngineTestFake {
2311 public:
2312 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2313 : WebRtcVoiceEngineTestFake(
2314 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2315 "Enabled/") {}
2316};
2317
2318TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2319 EXPECT_TRUE(SetupSendStream());
2320 cricket::AudioSendParameters parameters;
2321 parameters.codecs.push_back(kOpusCodec);
2322 SetSendParameters(parameters);
2323 const int initial_num = call_.GetNumCreatedSendStreams();
2324 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2325
2326 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2327 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002328 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2329 constexpr int kMinOverheadBps =
2330 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002331
2332 constexpr int kOpusMinBitrateBps = 6000;
2333 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002334 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002335 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002336 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002337 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002338
Oskar Sundbom78807582017-11-16 11:09:55 +01002339 parameters.options.audio_network_adaptor = true;
2340 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002341 SetSendParameters(parameters);
2342
ossu11bfc532017-02-16 05:37:06 -08002343 constexpr int kMinOverheadWithAnaBps =
2344 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002345
2346 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002347 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002348
minyuececec102017-03-27 13:04:25 -07002349 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002350 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002351}
2352
minyuececec102017-03-27 13:04:25 -07002353// This test is similar to
2354// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2355// additional field trial.
2356TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2357 SetRtpSendParameterUpdatesMaxBitrate) {
2358 EXPECT_TRUE(SetupSendStream());
2359 cricket::AudioSendParameters send_parameters;
2360 send_parameters.codecs.push_back(kOpusCodec);
2361 SetSendParameters(send_parameters);
2362
2363 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2364 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2365 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2366
2367 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002368 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
Zach Steinba37b4b2018-01-23 15:02:36 -08002369 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters).ok());
minyuececec102017-03-27 13:04:25 -07002370
2371 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2372#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2373 constexpr int kMinOverhead = 3333;
2374#else
2375 constexpr int kMinOverhead = 6666;
2376#endif
2377 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2378}
2379
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002380// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002381// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002382TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002383 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002384 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385}
2386
2387TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2388 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002389 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002390 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002391 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002392 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002393 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002394 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002395 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002396
solenberg85a04962015-10-27 03:35:21 -07002397 // Check stats for the added streams.
2398 {
2399 cricket::VoiceMediaInfo info;
2400 EXPECT_EQ(true, channel_->GetStats(&info));
2401
2402 // We have added one send stream. We should see the stats we've set.
2403 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002404 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002405 // We have added one receive stream. We should see empty stats.
2406 EXPECT_EQ(info.receivers.size(), 1u);
2407 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2408 }
solenberg1ac56142015-10-13 03:58:19 -07002409
solenberg566ef242015-11-06 15:34:49 -08002410 // Start sending - this affects some reported stats.
2411 {
2412 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002413 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002414 EXPECT_EQ(true, channel_->GetStats(&info));
2415 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002416 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002417 }
2418
solenberg2100c0b2017-03-01 11:29:29 -08002419 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002420 {
2421 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002422 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002423 EXPECT_EQ(true, channel_->GetStats(&info));
2424 EXPECT_EQ(1u, info.senders.size());
2425 EXPECT_EQ(0u, info.receivers.size());
2426 }
solenberg1ac56142015-10-13 03:58:19 -07002427
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002428 // Deliver a new packet - a default receive stream should be created and we
2429 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002430 {
2431 cricket::VoiceMediaInfo info;
2432 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2433 SetAudioReceiveStreamStats();
2434 EXPECT_EQ(true, channel_->GetStats(&info));
2435 EXPECT_EQ(1u, info.senders.size());
2436 EXPECT_EQ(1u, info.receivers.size());
2437 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002438 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002439 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440}
2441
2442// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002443// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002445 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002446 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2447 EXPECT_TRUE(AddRecvStream(kSsrcY));
2448 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449}
2450
2451// Test that the local SSRC is the same on sending and receiving channels if the
2452// receive channel is created before the send channel.
2453TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002454 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002455 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002456 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002457 cricket::StreamParams::CreateLegacy(kSsrcX)));
2458 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2459 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460}
2461
2462// Test that we can properly receive packets.
2463TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002464 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002465 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002467
2468 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2469 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470}
2471
2472// Test that we can properly receive packets on multiple streams.
2473TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002474 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002475 const uint32_t ssrc1 = 1;
2476 const uint32_t ssrc2 = 2;
2477 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002478 EXPECT_TRUE(AddRecvStream(ssrc1));
2479 EXPECT_TRUE(AddRecvStream(ssrc2));
2480 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002482 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002483 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002485 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486 }
mflodman3d7db262016-04-29 00:57:13 -07002487
2488 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2489 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2490 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2491
2492 EXPECT_EQ(s1.received_packets(), 0);
2493 EXPECT_EQ(s2.received_packets(), 0);
2494 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002495
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_EQ(s1.received_packets(), 0);
2498 EXPECT_EQ(s2.received_packets(), 0);
2499 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002500
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002502 EXPECT_EQ(s1.received_packets(), 1);
2503 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2504 EXPECT_EQ(s2.received_packets(), 0);
2505 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002506
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002508 EXPECT_EQ(s1.received_packets(), 1);
2509 EXPECT_EQ(s2.received_packets(), 1);
2510 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2511 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002512
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002514 EXPECT_EQ(s1.received_packets(), 1);
2515 EXPECT_EQ(s2.received_packets(), 1);
2516 EXPECT_EQ(s3.received_packets(), 1);
2517 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002518
mflodman3d7db262016-04-29 00:57:13 -07002519 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2520 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2521 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522}
2523
solenberg2100c0b2017-03-01 11:29:29 -08002524// Test that receiving on an unsignaled stream works (a stream is created).
2525TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002526 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002527 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2528
solenberg7e63ef02015-11-20 00:19:43 -08002529 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002530
2531 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002532 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2533 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002534}
2535
solenberg2100c0b2017-03-01 11:29:29 -08002536// Test that receiving N unsignaled stream works (streams will be created), and
2537// that packets are forwarded to them all.
2538TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002539 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002540 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002541 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2542
solenberg2100c0b2017-03-01 11:29:29 -08002543 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002544 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002545 rtc::SetBE32(&packet[8], ssrc);
2546 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002547
solenberg2100c0b2017-03-01 11:29:29 -08002548 // Verify we have one new stream for each loop iteration.
2549 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002550 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2551 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002552 }
mflodman3d7db262016-04-29 00:57:13 -07002553
solenberg2100c0b2017-03-01 11:29:29 -08002554 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002555 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002556 rtc::SetBE32(&packet[8], ssrc);
2557 DeliverPacket(packet, sizeof(packet));
2558
solenbergebb349d2017-03-13 05:46:15 -07002559 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002560 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2561 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2562 }
2563
2564 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2565 constexpr uint32_t kAnotherSsrc = 667;
2566 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002567 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002568
2569 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002570 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002571 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002572 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002573 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2574 EXPECT_EQ(2, streams[i]->received_packets());
2575 }
2576 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2577 EXPECT_EQ(1, streams[i]->received_packets());
2578 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002579 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002580}
2581
solenberg2100c0b2017-03-01 11:29:29 -08002582// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002583// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002584TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002585 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002586 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002587 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2588
2589 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002590 const uint32_t signaled_ssrc = 1;
2591 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002592 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002593 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002594 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2595 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002596 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002597
2598 // Note that the first unknown SSRC cannot be 0, because we only support
2599 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002600 const uint32_t unsignaled_ssrc = 7011;
2601 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002602 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002603 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2604 packet, sizeof(packet)));
2605 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2606
2607 DeliverPacket(packet, sizeof(packet));
2608 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2609
2610 rtc::SetBE32(&packet[8], signaled_ssrc);
2611 DeliverPacket(packet, sizeof(packet));
2612 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2613 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002614}
2615
solenberg4904fb62017-02-17 12:01:14 -08002616// Two tests to verify that adding a receive stream with the same SSRC as a
2617// previously added unsignaled stream will only recreate underlying stream
2618// objects if the stream parameters have changed.
2619TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2620 EXPECT_TRUE(SetupChannel());
2621
2622 // Spawn unsignaled stream with SSRC=1.
2623 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2624 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2625 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2626 sizeof(kPcmuFrame)));
2627
2628 // Verify that the underlying stream object in Call is not recreated when a
2629 // stream with SSRC=1 is added.
2630 const auto& streams = call_.GetAudioReceiveStreams();
2631 EXPECT_EQ(1, streams.size());
2632 int audio_receive_stream_id = streams.front()->id();
2633 EXPECT_TRUE(AddRecvStream(1));
2634 EXPECT_EQ(1, streams.size());
2635 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2636}
2637
2638TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2639 EXPECT_TRUE(SetupChannel());
2640
2641 // Spawn unsignaled stream with SSRC=1.
2642 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2643 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2644 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2645 sizeof(kPcmuFrame)));
2646
2647 // Verify that the underlying stream object in Call *is* recreated when a
2648 // stream with SSRC=1 is added, and which has changed stream parameters.
2649 const auto& streams = call_.GetAudioReceiveStreams();
2650 EXPECT_EQ(1, streams.size());
2651 int audio_receive_stream_id = streams.front()->id();
2652 cricket::StreamParams stream_params;
2653 stream_params.ssrcs.push_back(1);
2654 stream_params.sync_label = "sync_label";
2655 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2656 EXPECT_EQ(1, streams.size());
2657 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2658}
2659
solenberg1ac56142015-10-13 03:58:19 -07002660// Test that AddRecvStream creates new stream.
2661TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002662 EXPECT_TRUE(SetupRecvStream());
solenberg8189b022016-06-14 12:13:00 -07002663 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664}
2665
2666// Test that after adding a recv stream, we do not decode more codecs than
2667// those previously passed into SetRecvCodecs.
2668TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002669 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002670 cricket::AudioRecvParameters parameters;
2671 parameters.codecs.push_back(kIsacCodec);
2672 parameters.codecs.push_back(kPcmuCodec);
2673 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002674 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002675 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2676 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2677 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002678}
2679
2680// Test that we properly clean up any streams that were added, even if
2681// not explicitly removed.
2682TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002683 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002684 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002685 EXPECT_TRUE(AddRecvStream(1));
2686 EXPECT_TRUE(AddRecvStream(2));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002687
2688 EXPECT_EQ(1, call_.GetAudioSendStreams().size());
2689 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690 delete channel_;
2691 channel_ = NULL;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002692 EXPECT_EQ(0, call_.GetAudioSendStreams().size());
2693 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002694}
2695
wu@webrtc.org78187522013-10-07 23:32:02 +00002696TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002697 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002698 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002699}
2700
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002701TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithSameSsrc) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002703 EXPECT_TRUE(AddRecvStream(1));
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002704 EXPECT_FALSE(AddRecvStream(1));
wu@webrtc.org78187522013-10-07 23:32:02 +00002705}
2706
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002707// Test the InsertDtmf on default send stream as caller.
2708TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002709 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002710}
2711
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002712// Test the InsertDtmf on default send stream as callee
2713TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002714 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002715}
2716
2717// Test the InsertDtmf on specified send stream as caller.
2718TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002719 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002720}
2721
2722// Test the InsertDtmf on specified send stream as callee.
2723TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002724 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725}
2726
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002728 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002729 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg5b5129a2016-04-08 05:35:48 -07002730 EXPECT_CALL(adm_,
2731 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2732 EXPECT_CALL(adm_,
2733 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2734 EXPECT_CALL(adm_,
2735 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002736
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002737 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2738 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739
solenberg246b8172015-12-08 09:50:23 -08002740 // Nothing set in AudioOptions, so everything should be as default.
2741 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002742 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002743 EXPECT_TRUE(IsHighPassFilterEnabled());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01002744 EXPECT_EQ(50, GetRecvStreamConfig(kSsrcY).jitter_buffer_max_packets);
2745 EXPECT_FALSE(GetRecvStreamConfig(kSsrcY).jitter_buffer_fast_accelerate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746
2747 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002748 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2749 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002750 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002752
2753 // Turn echo cancellation back on, with settings, and make sure
2754 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002760 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2761 // control.
solenberg76377c52017-02-21 00:54:31 -08002762 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002764 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002765 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002766
2767 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002768 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2769 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002770 send_parameters_.options.delay_agnostic_aec = false;
2771 send_parameters_.options.extended_filter_aec = false;
2772 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002774
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002775 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002776 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002778 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002779 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002780
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002782 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2783 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002784 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002786 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002787 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788
2789 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002790 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002792 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002793 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002794 send_parameters_.options.auto_gain_control = true;
solenberg059fb442016-10-26 05:12:24 -07002795 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796
Fredrik Solenberg2a877972017-12-15 16:42:15 +01002797 // Turn off other options.
solenberg76377c52017-02-21 00:54:31 -08002798 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2799 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002800 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002801 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002802 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002803 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2804 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002805 send_parameters_.options.noise_suppression = false;
2806 send_parameters_.options.highpass_filter = false;
2807 send_parameters_.options.typing_detection = false;
2808 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002809 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002810 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811
solenberg1ac56142015-10-13 03:58:19 -07002812 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002813 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2814 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002815 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002816 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002817 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002818 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2819 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002820 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002821}
2822
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002824 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002825 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002826 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002827 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002828 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002829 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002830 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002831 EXPECT_CALL(adm_,
2832 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2833 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2834 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002835 webrtc::AudioProcessing::Config apm_config;
2836 EXPECT_CALL(*apm_, GetConfig())
2837 .Times(10)
2838 .WillRepeatedly(ReturnPointee(&apm_config));
2839 EXPECT_CALL(*apm_, ApplyConfig(_))
2840 .Times(10)
2841 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002842 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002843
kwiberg686a8ef2016-02-26 03:00:35 -08002844 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002845 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002846 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002847 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002848 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002849 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002850
2851 // Have to add a stream to make SetSend work.
2852 cricket::StreamParams stream1;
2853 stream1.ssrcs.push_back(1);
2854 channel1->AddSendStream(stream1);
2855 cricket::StreamParams stream2;
2856 stream2.ssrcs.push_back(2);
2857 channel2->AddSendStream(stream2);
2858
2859 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002860 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002861 parameters_options_all.options.echo_cancellation = true;
2862 parameters_options_all.options.auto_gain_control = true;
2863 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002864 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2865 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002866 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002867 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002868 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002869 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002870 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002872 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002873 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
2875 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002876 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002877 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002878 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2879 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002880 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002881 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002882 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002884 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002885 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002886 expected_options.echo_cancellation = true;
2887 expected_options.auto_gain_control = true;
2888 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002889 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002890
2891 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002892 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002893 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002894 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002896 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002898 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002900 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002901 expected_options.echo_cancellation = true;
2902 expected_options.auto_gain_control = false;
2903 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002904 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002908 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002909 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002910 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002912 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913
solenberg76377c52017-02-21 00:54:31 -08002914 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002916 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002917 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002918 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002919 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002920 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921
solenberg76377c52017-02-21 00:54:31 -08002922 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2923 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002924 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002925 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002926 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002927 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002928 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002931 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2932 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002933 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2934 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002935 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2936 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002937 EXPECT_CALL(apm_gc_, set_mode(kDefaultAgcMode)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002938 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Fredrik Solenberg55900fd2017-11-23 20:22:55 +01002939 EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -08002940 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002941 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002942 expected_options.echo_cancellation = true;
2943 expected_options.auto_gain_control = false;
2944 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002945 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946}
2947
wu@webrtc.orgde305012013-10-31 15:40:38 +00002948// This test verifies DSCP settings are properly applied on voice media channel.
2949TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002950 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002951 cricket::FakeNetworkInterface network_interface;
2952 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002953 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002954
peahb1c9d1d2017-07-25 15:45:24 -07002955 webrtc::AudioProcessing::Config apm_config;
2956 EXPECT_CALL(*apm_, GetConfig())
2957 .Times(3)
2958 .WillRepeatedly(ReturnPointee(&apm_config));
2959 EXPECT_CALL(*apm_, ApplyConfig(_))
2960 .Times(3)
2961 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002962 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002963
solenbergbc37fc82016-04-04 09:54:44 -07002964 channel.reset(
2965 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002966 channel->SetInterface(&network_interface);
2967 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2968 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2969
2970 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002971 channel.reset(
2972 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002973 channel->SetInterface(&network_interface);
2974 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2975
2976 // Verify that setting the option to false resets the
2977 // DiffServCodePoint.
2978 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002979 channel.reset(
2980 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002981 channel->SetInterface(&network_interface);
2982 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2983 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2984
2985 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002986}
2987
solenberg4bac9c52015-10-09 02:32:53 -07002988TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002989 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002990 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002992 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002994 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2995 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2996 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002997}
2998
solenberg2100c0b2017-03-01 11:29:29 -08002999TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003000 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003001
3002 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003003 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003004 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3005
3006 // Should remember the volume "2" which will be set on new unsignaled streams,
3007 // and also set the gain to 2 on existing unsignaled streams.
3008 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3009 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3010
3011 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3012 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3013 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3014 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3015 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3016 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3017
3018 // Setting gain with SSRC=0 should affect all unsignaled streams.
3019 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003020 if (kMaxUnsignaledRecvStreams > 1) {
3021 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3022 }
solenberg2100c0b2017-03-01 11:29:29 -08003023 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3024
3025 // Setting gain on an individual stream affects only that.
3026 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003027 if (kMaxUnsignaledRecvStreams > 1) {
3028 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3029 }
solenberg2100c0b2017-03-01 11:29:29 -08003030 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031}
3032
pbos8fc7fa72015-07-15 08:02:58 -07003033TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003034 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003035 const std::string kSyncLabel = "AvSyncLabel";
3036
solenbergff976312016-03-30 23:28:51 -07003037 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003038 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3039 sp.sync_label = kSyncLabel;
3040 // Creating two channels to make sure that sync label is set properly for both
3041 // the default voice channel and following ones.
3042 EXPECT_TRUE(channel_->AddRecvStream(sp));
3043 sp.ssrcs[0] += 1;
3044 EXPECT_TRUE(channel_->AddRecvStream(sp));
3045
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003046 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003047 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003048 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003049 << "SyncGroup should be set based on sync_label";
3050 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003051 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003052 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003053}
3054
solenberg3a941542015-11-16 07:34:50 -08003055// TODO(solenberg): Remove, once recv streams are configured through Call.
3056// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003057TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003058 // Test that setting the header extensions results in the expected state
3059 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003060 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003061 ssrcs.push_back(223);
3062 ssrcs.push_back(224);
3063
solenbergff976312016-03-30 23:28:51 -07003064 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003065 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003066 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003067 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003068 cricket::StreamParams::CreateLegacy(ssrc)));
3069 }
3070
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003071 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003072 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003073 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003074 EXPECT_NE(nullptr, s);
3075 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3076 }
3077
3078 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003079 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003080 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003081 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003082 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003084 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003085 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003086 EXPECT_NE(nullptr, s);
3087 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003088 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3089 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003090 for (const auto& s_ext : s_exts) {
3091 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003092 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093 }
3094 }
3095 }
3096 }
3097
3098 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003099 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003100 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003101 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102 EXPECT_NE(nullptr, s);
3103 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3104 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105}
3106
3107TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3108 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003109 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003110 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003111 static const unsigned char kRtcp[] = {
3112 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3113 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3116 };
jbaucheec21bd2016-03-20 06:15:43 -07003117 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003118
solenbergff976312016-03-30 23:28:51 -07003119 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003120 cricket::WebRtcVoiceMediaChannel* media_channel =
3121 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003122 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123 EXPECT_TRUE(media_channel->AddRecvStream(
3124 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3125
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003126 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003128 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003129 EXPECT_EQ(0, s->received_packets());
3130 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3131 EXPECT_EQ(1, s->received_packets());
3132 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3133 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134}
Minyue2013aec2015-05-13 14:14:42 +02003135
solenberg0a617e22015-10-20 15:49:38 -07003136// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003137// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003138TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003139 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003140 EXPECT_TRUE(AddRecvStream(kSsrcY));
3141 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003142 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003143 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3144 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3145 EXPECT_TRUE(AddRecvStream(kSsrcW));
3146 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003147}
3148
solenberg7602aab2016-11-14 11:30:07 -08003149TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3150 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003151 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003152 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003153 cricket::StreamParams::CreateLegacy(kSsrcY)));
3154 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3155 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3156 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003157 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003158 cricket::StreamParams::CreateLegacy(kSsrcW)));
3159 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3160 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003161}
stefan658910c2015-09-03 05:48:32 -07003162
deadbeef884f5852016-01-15 09:20:04 -08003163TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003164 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003165 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3166 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003167
3168 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003169 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3170 EXPECT_TRUE(AddRecvStream(kSsrcX));
3171 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003172
3173 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003174 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3175 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003176
3177 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003178 channel_->SetRawAudioSink(kSsrcX, nullptr);
3179 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003180}
3181
solenberg2100c0b2017-03-01 11:29:29 -08003182TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003183 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003184 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3185 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003186 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3187 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003188
3189 // Should be able to set a default sink even when no stream exists.
3190 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3191
solenberg2100c0b2017-03-01 11:29:29 -08003192 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3193 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003194 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003195 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003196
3197 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003198 channel_->SetRawAudioSink(kSsrc0, nullptr);
3199 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003200
3201 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003202 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3203 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003204
3205 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003206 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003207 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003208 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3209
3210 // Spawn another unsignaled stream - it should be assigned the default sink
3211 // and the previous unsignaled stream should lose it.
3212 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3213 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3214 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3215 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003216 if (kMaxUnsignaledRecvStreams > 1) {
3217 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3218 }
solenberg2100c0b2017-03-01 11:29:29 -08003219 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3220
3221 // Reset the default sink - the second unsignaled stream should lose it.
3222 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003223 if (kMaxUnsignaledRecvStreams > 1) {
3224 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3225 }
solenberg2100c0b2017-03-01 11:29:29 -08003226 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3227
3228 // Try setting the default sink while two streams exists.
3229 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003230 if (kMaxUnsignaledRecvStreams > 1) {
3231 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3232 }
solenberg2100c0b2017-03-01 11:29:29 -08003233 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3234
3235 // Try setting the sink for the first unsignaled stream using its known SSRC.
3236 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003237 if (kMaxUnsignaledRecvStreams > 1) {
3238 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3239 }
solenberg2100c0b2017-03-01 11:29:29 -08003240 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003241 if (kMaxUnsignaledRecvStreams > 1) {
3242 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3243 }
deadbeef884f5852016-01-15 09:20:04 -08003244}
3245
skvlad7a43d252016-03-22 15:32:27 -07003246// Test that, just like the video channel, the voice channel communicates the
3247// network state to the call.
3248TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003249 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003250
3251 EXPECT_EQ(webrtc::kNetworkUp,
3252 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3253 EXPECT_EQ(webrtc::kNetworkUp,
3254 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3255
3256 channel_->OnReadyToSend(false);
3257 EXPECT_EQ(webrtc::kNetworkDown,
3258 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3259 EXPECT_EQ(webrtc::kNetworkUp,
3260 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3261
3262 channel_->OnReadyToSend(true);
3263 EXPECT_EQ(webrtc::kNetworkUp,
3264 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3265 EXPECT_EQ(webrtc::kNetworkUp,
3266 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3267}
3268
aleloi18e0b672016-10-04 02:45:47 -07003269// Test that playout is still started after changing parameters
3270TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3271 SetupRecvStream();
3272 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003273 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003274
3275 // Changing RTP header extensions will recreate the AudioReceiveStream.
3276 cricket::AudioRecvParameters parameters;
3277 parameters.extensions.push_back(
3278 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3279 channel_->SetRecvParameters(parameters);
3280
solenberg2100c0b2017-03-01 11:29:29 -08003281 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003282}
3283
Zhi Huangfa266ef2017-12-13 10:27:46 -08003284// Tests when GetSources is called with non-existing ssrc, it will return an
3285// empty list of RtpSource without crashing.
3286TEST_F(WebRtcVoiceEngineTestFake, GetSourcesWithNonExistingSsrc) {
3287 // Setup an recv stream with |kSsrcX|.
3288 SetupRecvStream();
3289 cricket::WebRtcVoiceMediaChannel* media_channel =
3290 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3291 // Call GetSources with |kSsrcY| which doesn't exist.
3292 std::vector<webrtc::RtpSource> sources = media_channel->GetSources(kSsrcY);
3293 EXPECT_EQ(0u, sources.size());
3294}
3295
stefan658910c2015-09-03 05:48:32 -07003296// Tests that the library initializes and shuts down properly.
3297TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003298 // If the VoiceEngine wants to gather available codecs early, that's fine but
3299 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003300 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003301 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003302 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003303 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003304 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003305 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003306 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003307 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003308 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003309 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003310 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3311 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003312 EXPECT_TRUE(channel != nullptr);
3313 delete channel;
solenbergff976312016-03-30 23:28:51 -07003314}
stefan658910c2015-09-03 05:48:32 -07003315
solenbergff976312016-03-30 23:28:51 -07003316// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003317TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3318 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003319 EXPECT_CALL(adm, AddRef()).Times(3);
Niels Möller6f72f562017-10-19 13:15:17 +02003320 EXPECT_CALL(adm, Release())
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +01003321 .Times(3)
Niels Möller6f72f562017-10-19 13:15:17 +02003322 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003323 {
peaha9cc40b2017-06-29 08:32:09 -07003324 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003325 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003326 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003327 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003328 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003329 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003330 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003331 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003332 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003333 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3334 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3335 EXPECT_TRUE(channel != nullptr);
3336 delete channel;
3337 }
stefan658910c2015-09-03 05:48:32 -07003338}
3339
ossu20a4b3f2017-04-27 02:08:52 -07003340// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3341TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003342 // TODO(ossu): Why are the payload types of codecs with non-static payload
3343 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003344 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003345 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003346 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003347 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003348 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003349 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003350 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003351 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003352 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3353 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3354 (clockrate == 0 || codec.clockrate == clockrate);
3355 };
3356 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003358 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003359 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003360 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003361 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003362 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003363 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003364 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003365 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003366 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003367 EXPECT_EQ(126, codec.id);
3368 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3369 // Remove these checks once both send and receive side assigns payload types
3370 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003373 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003374 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003375 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003376 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003377 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003378 EXPECT_EQ(111, codec.id);
3379 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3380 EXPECT_EQ("10", codec.params.find("minptime")->second);
3381 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3382 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003383 }
3384 }
stefan658910c2015-09-03 05:48:32 -07003385}
3386
3387// Tests that VoE supports at least 32 channels
3388TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003389 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003390 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003391 webrtc::AudioProcessingBuilder().Create();
ossuc54071d2016-08-17 02:45:41 -07003392 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003393 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003394 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003395 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003396 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003397 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003398 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003399
3400 cricket::VoiceMediaChannel* channels[32];
3401 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003402 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003403 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3404 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003405 if (!channel)
3406 break;
stefan658910c2015-09-03 05:48:32 -07003407 channels[num_channels++] = channel;
3408 }
3409
tfarina5237aaf2015-11-10 23:44:30 -08003410 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003411 EXPECT_EQ(expected, num_channels);
3412
3413 while (num_channels > 0) {
3414 delete channels[--num_channels];
3415 }
stefan658910c2015-09-03 05:48:32 -07003416}
3417
3418// Test that we set our preferred codecs properly.
3419TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003420 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3421 // - Check that our builtin codecs are usable by Channel.
3422 // - The codecs provided by the engine is usable by Channel.
3423 // It does not check that the codecs in the RecvParameters are actually
3424 // what we sent in - though it's probably reasonable to expect so, if
3425 // SetRecvParameters returns true.
3426 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003427 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003428 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003429 webrtc::AudioProcessingBuilder().Create();
ossu29b1a8d2016-06-13 07:34:51 -07003430 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003431 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003432 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003433 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003434 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003435 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003436 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003437 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3438 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003439 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003440 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003441 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003442}
ossu9def8002017-02-09 05:14:32 -08003443
3444TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3445 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003446 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3447 {48000, 2, 16000, 10000, 20000}};
3448 spec1.info.allow_comfort_noise = false;
3449 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003450 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003451 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3452 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003453 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003454 specs.push_back(webrtc::AudioCodecSpec{
3455 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3456 {16000, 1, 13300}});
3457 specs.push_back(
3458 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3459 specs.push_back(
3460 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003461
ossueb1fde42017-05-02 06:46:30 -07003462 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3463 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3464 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003465 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003466 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003467 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003468 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003469
peaha9cc40b2017-06-29 08:32:09 -07003470 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
Ivo Creusen62337e52018-01-09 14:17:33 +01003471 webrtc::AudioProcessingBuilder().Create();
henrika919dc2e2017-10-12 14:24:55 +02003472 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003473 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003474 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003475 auto codecs = engine.recv_codecs();
3476 EXPECT_EQ(11, codecs.size());
3477
3478 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3479 // check the actual values safely, to provide better test results.
3480 auto get_codec =
3481 [&codecs](size_t index) -> const cricket::AudioCodec& {
3482 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3483 if (codecs.size() > index)
3484 return codecs[index];
3485 return missing_codec;
3486 };
3487
3488 // Ensure the general codecs are generated first and in order.
3489 for (size_t i = 0; i != specs.size(); ++i) {
3490 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3491 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3492 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3493 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3494 }
3495
3496 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003497 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003498 auto find_codec =
3499 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3500 for (size_t i = 0; i != codecs.size(); ++i) {
3501 const cricket::AudioCodec& codec = codecs[i];
3502 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3503 codec.clockrate == format.clockrate_hz &&
3504 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003505 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003506 }
3507 }
3508 return -1;
3509 };
3510
3511 // Ensure all supplementary codecs are generated last. Their internal ordering
3512 // is not important.
3513 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3514 const int num_specs = static_cast<int>(specs.size());
3515 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3516 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3517 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3518 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3519 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3520 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3521 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3522}