blob: d5743ca2eca5053eab99f593364c750b05a4d651 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070014#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
ossuf515ab82016-12-07 04:52:58 -080015#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070016#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080017#include "webrtc/media/base/fakemediaengine.h"
18#include "webrtc/media/base/fakenetworkinterface.h"
19#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080020#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/fakewebrtccall.h"
22#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
23#include "webrtc/media/engine/webrtcvoiceengine.h"
solenbergbc37fc82016-04-04 09:54:44 -070024#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070025#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080026#include "webrtc/pc/channel.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020027#include "webrtc/rtc_base/arraysize.h"
28#include "webrtc/rtc_base/byteorder.h"
29#include "webrtc/rtc_base/safe_conversions.h"
30#include "webrtc/rtc_base/scoped_ref_ptr.h"
kwiberg087bd342017-02-10 08:15:44 -080031#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080032#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070033#include "webrtc/test/mock_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070034#include "webrtc/test/mock_audio_encoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080035#include "webrtc/voice_engine/transmit_mixer.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
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070class FakeVoEWrapper : public cricket::VoEWrapper {
71 public:
72 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070073 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 }
75};
skvlad11a9cbf2016-10-07 11:53:05 -070076
solenberg76377c52017-02-21 00:54:31 -080077class MockTransmitMixer : public webrtc::voe::TransmitMixer {
78 public:
79 MockTransmitMixer() = default;
80 virtual ~MockTransmitMixer() = default;
81
82 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
83};
solenberg9a5f032222017-03-15 06:14:12 -070084
85void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
86 RTC_DCHECK(adm);
87 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
88 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
89#if !defined(WEBRTC_IOS)
90 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
91 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
92 ChannelType::kChannelBoth)).WillOnce(Return(0));
93#if defined(WEBRTC_WIN)
94 EXPECT_CALL(*adm, SetRecordingDevice(
95 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
96 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
97 .WillOnce(Return(0));
98#else
99 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
100#endif // #if defined(WEBRTC_WIN)
101 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
102 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
103 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
104 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
105#if defined(WEBRTC_WIN)
106 EXPECT_CALL(*adm, SetPlayoutDevice(
107 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
108 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
109 .WillOnce(Return(0));
110#else
111 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
112#endif // #if defined(WEBRTC_WIN)
113 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
114 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
115 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
116#endif // #if !defined(WEBRTC_IOS)
117 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
118 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
119 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
121}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200122} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123
solenbergff976312016-03-30 23:28:51 -0700124// Tests that our stub library "works".
125TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700126 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700127 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700128 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
129 new rtc::RefCountedObject<
130 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700131 webrtc::AudioProcessing::Config apm_config;
132 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
133 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700134 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
135 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
136 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800137 StrictMock<MockTransmitMixer> transmit_mixer;
138 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700139 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700140 EXPECT_FALSE(voe.IsInited());
141 {
ossuc54071d2016-08-17 02:45:41 -0700142 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700143 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700144 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700145 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700146 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700147 EXPECT_TRUE(voe.IsInited());
148 }
149 EXPECT_FALSE(voe.IsInited());
150}
151
deadbeef884f5852016-01-15 09:20:04 -0800152class FakeAudioSink : public webrtc::AudioSinkInterface {
153 public:
154 void OnData(const Data& audio) override {}
155};
156
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800157class FakeAudioSource : public cricket::AudioSource {
158 void SetSink(Sink* sink) override {}
159};
160
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161class WebRtcVoiceEngineTestFake : public testing::Test {
162 public:
stefanba4c0e42016-02-04 04:12:24 -0800163 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
164
165 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700166 : apm_(new rtc::RefCountedObject<
167 StrictMock<webrtc::test::MockAudioProcessing>>()),
168 apm_gc_(*apm_->gain_control()),
169 apm_ec_(*apm_->echo_cancellation()),
170 apm_ns_(*apm_->noise_suppression()),
171 apm_vd_(*apm_->voice_detection()),
172 call_(webrtc::Call::Config(&event_log_)),
173 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700174 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800175 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700176 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800177 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700178 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
179 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700180 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
181 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
182 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800183 // Default Options.
184 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
185 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
186 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
190 // Init does not overwrite default AGC config.
191 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
192 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
193 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
194 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
195 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
196 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700197 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800198 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700199 // factories. Those tests should probably be moved elsewhere.
200 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
201 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
202 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700203 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700204 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700205 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200206 send_parameters_.codecs.push_back(kPcmuCodec);
207 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800208 // Default Options.
209 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
solenberg8189b022016-06-14 12:13:00 -0700211
solenbergff976312016-03-30 23:28:51 -0700212 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700213 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700214 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
215 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000217 }
solenberg8189b022016-06-14 12:13:00 -0700218
solenbergff976312016-03-30 23:28:51 -0700219 bool SetupRecvStream() {
220 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700221 return false;
222 }
solenberg2100c0b2017-03-01 11:29:29 -0800223 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700224 }
solenberg8189b022016-06-14 12:13:00 -0700225
solenbergff976312016-03-30 23:28:51 -0700226 bool SetupSendStream() {
227 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000228 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 }
solenberg2100c0b2017-03-01 11:29:29 -0800230 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800231 return false;
232 }
peaha9cc40b2017-06-29 08:32:09 -0700233 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800234 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 }
solenberg8189b022016-06-14 12:13:00 -0700236
237 bool AddRecvStream(uint32_t ssrc) {
238 EXPECT_TRUE(channel_);
239 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
240 }
241
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000242 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700243 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700244 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800245 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
246 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700247 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800248 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249 }
solenberg8189b022016-06-14 12:13:00 -0700250
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700252 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000253 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200256 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 }
259
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100260 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
261 const auto* send_stream = call_.GetAudioSendStream(ssrc);
262 EXPECT_TRUE(send_stream);
263 return *send_stream;
264 }
265
deadbeef884f5852016-01-15 09:20:04 -0800266 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
267 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
268 EXPECT_TRUE(recv_stream);
269 return *recv_stream;
270 }
271
solenberg3a941542015-11-16 07:34:50 -0800272 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800273 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800274 }
275
solenberg7add0582015-11-20 09:59:34 -0800276 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800277 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800278 }
279
solenberg059fb442016-10-26 05:12:24 -0700280 void SetSend(bool enable) {
281 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700282 if (enable) {
283 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
284 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
285 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700286 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700287 }
solenberg059fb442016-10-26 05:12:24 -0700288 channel_->SetSend(enable);
289 }
290
291 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700292 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700293 ASSERT_TRUE(channel_);
294 EXPECT_TRUE(channel_->SetSendParameters(params));
295 }
296
minyue6b825df2016-10-31 04:08:32 -0700297 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
298 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700299 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700300 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700301 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700302 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700303 }
304 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700305 }
306
solenbergffbbcac2016-11-17 05:25:37 -0800307 void TestInsertDtmf(uint32_t ssrc, bool caller,
308 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700309 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700311 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 // send stream.
313 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800314 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000316
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700318 SetSendParameters(send_parameters_);
319 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800322 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000325
326 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700327 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800328 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800330 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331 }
332
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800334 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100336 // Test send.
337 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800338 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100339 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800340 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800341 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800342 EXPECT_EQ(codec.id, telephone_event.payload_type);
343 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(2, telephone_event.event_code);
345 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 }
347
348 // Test that send bandwidth is set correctly.
349 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000350 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
351 // |expected_result| is the expected result from SetMaxSendBandwidth().
352 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700353 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
354 int max_bitrate,
355 bool expected_result,
356 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200357 cricket::AudioSendParameters parameters;
358 parameters.codecs.push_back(codec);
359 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700360 if (expected_result) {
361 SetSendParameters(parameters);
362 } else {
363 EXPECT_FALSE(channel_->SetSendParameters(parameters));
364 }
solenberg2100c0b2017-03-01 11:29:29 -0800365 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366 }
367
skvlade0d46372016-04-07 22:59:22 -0700368 // Sets the per-stream maximum bitrate limit for the specified SSRC.
369 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700370 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700371 EXPECT_EQ(1UL, parameters.encodings.size());
372
deadbeefe702b302017-02-04 12:09:01 -0800373 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700374 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700375 }
376
solenberg059fb442016-10-26 05:12:24 -0700377 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700378 cricket::AudioSendParameters send_parameters;
379 send_parameters.codecs.push_back(codec);
380 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700381 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700382 }
383
ossu20a4b3f2017-04-27 02:08:52 -0700384 void CheckSendCodecBitrate(int32_t ssrc,
385 const char expected_name[],
386 int expected_bitrate) {
387 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
388 EXPECT_EQ(expected_name, spec->format.name);
389 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700390 }
391
ossu20a4b3f2017-04-27 02:08:52 -0700392 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
393 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700394 }
395
minyue6b825df2016-10-31 04:08:32 -0700396 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
397 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
401 int global_max,
402 int stream_max,
403 bool expected_result,
404 int expected_codec_bitrate) {
405 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800406 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700407
408 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700409 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800410 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700411
412 // Verify that reading back the parameters gives results
413 // consistent with the Set() result.
414 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800415 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700416 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
417 EXPECT_EQ(expected_result ? stream_max : -1,
418 resulting_parameters.encodings[0].max_bitrate_bps);
419
420 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800421 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700422 }
423
stefan13f1a0a2016-11-30 07:22:58 -0800424 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
425 int expected_min_bitrate_bps,
426 const char* start_bitrate_kbps,
427 int expected_start_bitrate_bps,
428 const char* max_bitrate_kbps,
429 int expected_max_bitrate_bps) {
430 EXPECT_TRUE(SetupSendStream());
431 auto& codecs = send_parameters_.codecs;
432 codecs.clear();
433 codecs.push_back(kOpusCodec);
434 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
436 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
437 SetSendParameters(send_parameters_);
438
439 EXPECT_EQ(expected_min_bitrate_bps,
440 call_.GetConfig().bitrate_config.min_bitrate_bps);
441 EXPECT_EQ(expected_start_bitrate_bps,
442 call_.GetConfig().bitrate_config.start_bitrate_bps);
443 EXPECT_EQ(expected_max_bitrate_bps,
444 call_.GetConfig().bitrate_config.max_bitrate_bps);
445 }
446
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000447 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700448 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
453 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(
455 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700461 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800462 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 // Ensure extension is set properly.
465 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700466 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700467 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
solenberg7add0582015-11-20 09:59:34 -0800472 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800474 cricket::StreamParams::CreateLegacy(kSsrcY)));
475 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
476 call_.GetAudioSendStream(kSsrcY));
477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200482 send_parameters_.codecs.push_back(kPcmuCodec);
483 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 }
488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700490 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
495 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(
497 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800498 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800502 recv_parameters_.extensions.clear();
503 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 // Ensure extension is set properly.
507 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700508 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800509 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
511 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
solenberg7add0582015-11-20 09:59:34 -0800514 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_TRUE(AddRecvStream(kSsrcY));
516 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
517 call_.GetAudioReceiveStream(kSsrcY));
518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521
522 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800523 recv_parameters_.extensions.clear();
524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000527 }
528
solenberg85a04962015-10-27 03:35:21 -0700529 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
530 webrtc::AudioSendStream::Stats stats;
531 stats.local_ssrc = 12;
532 stats.bytes_sent = 345;
533 stats.packets_sent = 678;
534 stats.packets_lost = 9012;
535 stats.fraction_lost = 34.56f;
536 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800537 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700538 stats.ext_seqnum = 789;
539 stats.jitter_ms = 12;
540 stats.rtt_ms = 345;
541 stats.audio_level = 678;
542 stats.aec_quality_min = 9.01f;
543 stats.echo_delay_median_ms = 234;
544 stats.echo_delay_std_ms = 567;
545 stats.echo_return_loss = 890;
546 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700547 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800548 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700549 stats.typing_noise_detected = true;
550 return stats;
551 }
552 void SetAudioSendStreamStats() {
553 for (auto* s : call_.GetAudioSendStreams()) {
554 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200555 }
solenberg85a04962015-10-27 03:35:21 -0700556 }
solenberg566ef242015-11-06 15:34:49 -0800557 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
558 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700559 const auto stats = GetAudioSendStreamStats();
560 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
561 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
562 EXPECT_EQ(info.packets_sent, stats.packets_sent);
563 EXPECT_EQ(info.packets_lost, stats.packets_lost);
564 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
565 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800566 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700567 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
568 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
569 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
570 EXPECT_EQ(info.audio_level, stats.audio_level);
571 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
572 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
573 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
574 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
575 EXPECT_EQ(info.echo_return_loss_enhancement,
576 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700577 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800578 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
579 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800580 EXPECT_EQ(info.typing_noise_detected,
581 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700582 }
583
584 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
585 webrtc::AudioReceiveStream::Stats stats;
586 stats.remote_ssrc = 123;
587 stats.bytes_rcvd = 456;
588 stats.packets_rcvd = 768;
589 stats.packets_lost = 101;
590 stats.fraction_lost = 23.45f;
591 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800592 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700593 stats.ext_seqnum = 678;
594 stats.jitter_ms = 901;
595 stats.jitter_buffer_ms = 234;
596 stats.jitter_buffer_preferred_ms = 567;
597 stats.delay_estimate_ms = 890;
598 stats.audio_level = 1234;
599 stats.expand_rate = 5.67f;
600 stats.speech_expand_rate = 8.90f;
601 stats.secondary_decoded_rate = 1.23f;
602 stats.accelerate_rate = 4.56f;
603 stats.preemptive_expand_rate = 7.89f;
604 stats.decoding_calls_to_silence_generator = 12;
605 stats.decoding_calls_to_neteq = 345;
606 stats.decoding_normal = 67890;
607 stats.decoding_plc = 1234;
608 stats.decoding_cng = 5678;
609 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700610 stats.decoding_muted_output = 3456;
611 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200612 return stats;
613 }
614 void SetAudioReceiveStreamStats() {
615 for (auto* s : call_.GetAudioReceiveStreams()) {
616 s->SetStats(GetAudioReceiveStreamStats());
617 }
618 }
619 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700620 const auto stats = GetAudioReceiveStreamStats();
621 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
622 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
623 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
624 EXPECT_EQ(info.packets_lost, stats.packets_lost);
625 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
626 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800627 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700628 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
629 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
630 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200631 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700632 stats.jitter_buffer_preferred_ms);
633 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
634 EXPECT_EQ(info.audio_level, stats.audio_level);
635 EXPECT_EQ(info.expand_rate, stats.expand_rate);
636 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
637 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
638 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
639 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200640 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700641 stats.decoding_calls_to_silence_generator);
642 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
643 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
644 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
645 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
646 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700647 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700648 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200649 }
hbos1acfbd22016-11-17 23:43:29 -0800650 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
651 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
652 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
653 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
654 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
655 codec.ToCodecParameters());
656 }
657 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
658 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
659 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
660 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
661 codec.ToCodecParameters());
662 }
663 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200664
peah8271d042016-11-22 07:24:52 -0800665 bool IsHighPassFilterEnabled() {
666 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
667 }
668
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700670 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700671 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800672 webrtc::test::MockGainControl& apm_gc_;
673 webrtc::test::MockEchoCancellation& apm_ec_;
674 webrtc::test::MockNoiseSuppression& apm_ns_;
675 webrtc::test::MockVoiceDetection& apm_vd_;
676 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700677 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200678 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700680 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700681 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200682 cricket::AudioSendParameters send_parameters_;
683 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800684 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700685 webrtc::AudioProcessing::Config apm_config_;
686
stefanba4c0e42016-02-04 04:12:24 -0800687 private:
688 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689};
690
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691// Tests that we can create and destroy a channel.
692TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700693 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694}
695
solenberg31fec402016-05-06 02:13:12 -0700696// Test that we can add a send stream and that it has the correct defaults.
697TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
698 EXPECT_TRUE(SetupChannel());
699 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800700 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
701 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
702 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700703 EXPECT_EQ("", config.rtp.c_name);
704 EXPECT_EQ(0u, config.rtp.extensions.size());
705 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
706 config.send_transport);
707}
708
709// Test that we can add a receive stream and that it has the correct defaults.
710TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
711 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800712 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700713 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800714 GetRecvStreamConfig(kSsrcX);
715 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700716 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
717 EXPECT_FALSE(config.rtp.transport_cc);
718 EXPECT_EQ(0u, config.rtp.extensions.size());
719 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
720 config.rtcp_send_transport);
721 EXPECT_EQ("", config.sync_group);
722}
723
stefanba4c0e42016-02-04 04:12:24 -0800724TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700725 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800726 bool opus_found = false;
727 for (cricket::AudioCodec codec : codecs) {
728 if (codec.name == "opus") {
729 EXPECT_TRUE(HasTransportCc(codec));
730 opus_found = true;
731 }
732 }
733 EXPECT_TRUE(opus_found);
734}
735
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736// Test that we set our inbound codecs properly, including changing PT.
737TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700738 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200739 cricket::AudioRecvParameters parameters;
740 parameters.codecs.push_back(kIsacCodec);
741 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800742 parameters.codecs.push_back(kTelephoneEventCodec1);
743 parameters.codecs.push_back(kTelephoneEventCodec2);
744 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200745 parameters.codecs[2].id = 126;
746 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800747 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700748 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
749 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
750 {{0, {"PCMU", 8000, 1}},
751 {106, {"ISAC", 16000, 1}},
752 {126, {"telephone-event", 8000, 1}},
753 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754}
755
756// Test that we fail to set an unknown inbound codec.
757TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700758 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200759 cricket::AudioRecvParameters parameters;
760 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700761 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200762 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763}
764
765// Test that we fail if we have duplicate types in the inbound list.
766TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700767 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200768 cricket::AudioRecvParameters parameters;
769 parameters.codecs.push_back(kIsacCodec);
770 parameters.codecs.push_back(kCn16000Codec);
771 parameters.codecs[1].id = kIsacCodec.id;
772 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773}
774
775// Test that we can decode OPUS without stereo parameters.
776TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700777 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200778 cricket::AudioRecvParameters parameters;
779 parameters.codecs.push_back(kIsacCodec);
780 parameters.codecs.push_back(kPcmuCodec);
781 parameters.codecs.push_back(kOpusCodec);
782 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800783 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700784 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
785 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
786 {{0, {"PCMU", 8000, 1}},
787 {103, {"ISAC", 16000, 1}},
788 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we can decode OPUS with stereo = 0.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
796 parameters.codecs.push_back(kPcmuCodec);
797 parameters.codecs.push_back(kOpusCodec);
798 parameters.codecs[2].params["stereo"] = "0";
799 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800800 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700801 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
802 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
803 {{0, {"PCMU", 8000, 1}},
804 {103, {"ISAC", 16000, 1}},
805 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806}
807
808// Test that we can decode OPUS with stereo = 1.
809TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700810 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200811 cricket::AudioRecvParameters parameters;
812 parameters.codecs.push_back(kIsacCodec);
813 parameters.codecs.push_back(kPcmuCodec);
814 parameters.codecs.push_back(kOpusCodec);
815 parameters.codecs[2].params["stereo"] = "1";
816 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800817 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700818 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
819 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
820 {{0, {"PCMU", 8000, 1}},
821 {103, {"ISAC", 16000, 1}},
822 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that changes to recv codecs are applied to all streams.
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
830 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800831 parameters.codecs.push_back(kTelephoneEventCodec1);
832 parameters.codecs.push_back(kTelephoneEventCodec2);
833 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 parameters.codecs[2].id = 126;
835 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700836 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
837 EXPECT_TRUE(AddRecvStream(ssrc));
838 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
839 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
840 {{0, {"PCMU", 8000, 1}},
841 {106, {"ISAC", 16000, 1}},
842 {126, {"telephone-event", 8000, 1}},
843 {107, {"telephone-event", 32000, 1}}})));
844 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700848 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200849 cricket::AudioRecvParameters parameters;
850 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800851 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200852 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853
solenberg2100c0b2017-03-01 11:29:29 -0800854 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800855 ASSERT_EQ(1, dm.count(106));
856 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857}
858
859// Test that we can apply the same set of codecs again while playing.
860TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700861 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200862 cricket::AudioRecvParameters parameters;
863 parameters.codecs.push_back(kIsacCodec);
864 parameters.codecs.push_back(kCn16000Codec);
865 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700866 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868
deadbeefcb383672017-04-26 16:28:42 -0700869 // Remapping a payload type to a different codec should fail.
870 parameters.codecs[0] = kOpusCodec;
871 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200872 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800873 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874}
875
876// Test that we can add a codec while playing.
877TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
881 parameters.codecs.push_back(kCn16000Codec);
882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700883 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 parameters.codecs.push_back(kOpusCodec);
886 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800887 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888}
889
deadbeefcb383672017-04-26 16:28:42 -0700890// Test that we accept adding the same codec with a different payload type.
891// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
892TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
893 EXPECT_TRUE(SetupRecvStream());
894 cricket::AudioRecvParameters parameters;
895 parameters.codecs.push_back(kIsacCodec);
896 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
897
898 ++parameters.codecs[0].id;
899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
900}
901
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700903 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000905 // Test that when autobw is enabled, bitrate is kept as the default
906 // value. autobw is enabled for the following tests because the target
907 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908
909 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700910 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911
912 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700913 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
ossu20a4b3f2017-04-27 02:08:52 -0700915 // opus, default bitrate == 32000 in mono.
916 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917}
918
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000919TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700920 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700923 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
924 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700925 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700928 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
929 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
930 // Rates above the max (510000) should be capped.
931 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932}
933
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000934TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000936
937 // Test that we can only set a maximum bitrate for a fixed-rate codec
938 // if it's bigger than the fixed rate.
939
940 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700941 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
942 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
943 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
944 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
945 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
946 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
947 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000948}
949
950TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700951 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952 const int kDesiredBitrate = 128000;
953 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700954 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200955 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700956 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000957
958 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800959 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000960
solenberg2100c0b2017-03-01 11:29:29 -0800961 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000962}
963
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964// Test that bitrate cannot be set for CBR codecs.
965// Bitrate is ignored if it is higher than the fixed bitrate.
966// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000967TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700968 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969
970 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800972 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200973
974 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700975 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800976 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200977
978 send_parameters_.max_bandwidth_bps = 128;
979 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800980 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
skvlade0d46372016-04-07 22:59:22 -0700983// Test that the per-stream bitrate limit and the global
984// bitrate limit both apply.
985TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
986 EXPECT_TRUE(SetupSendStream());
987
ossu20a4b3f2017-04-27 02:08:52 -0700988 // opus, default bitrate == 32000.
989 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700990 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
991 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
992 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
993
994 // CBR codecs allow both maximums to exceed the bitrate.
995 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
996 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
997 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
998 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
999
1000 // CBR codecs don't allow per stream maximums to be too low.
1001 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1002 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1003}
1004
1005// Test that an attempt to set RtpParameters for a stream that does not exist
1006// fails.
1007TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1008 EXPECT_TRUE(SetupChannel());
1009 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001010 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001011 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1012
1013 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001014 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001015}
1016
1017TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001018 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001019 // This test verifies that setting RtpParameters succeeds only if
1020 // the structure contains exactly one encoding.
1021 // TODO(skvlad): Update this test when we start supporting setting parameters
1022 // for each encoding individually.
1023
1024 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001025 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001026 // Two or more encodings should result in failure.
1027 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001028 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001029 // Zero encodings should also fail.
1030 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001031 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001032}
1033
1034// Changing the SSRC through RtpParameters is not allowed.
1035TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1036 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001037 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001038 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001039 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001040}
1041
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001042// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001043// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001044TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1045 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001046 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001047 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001048 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001049 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001050 ASSERT_EQ(1u, parameters.encodings.size());
1051 ASSERT_TRUE(parameters.encodings[0].active);
1052 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001053 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1054 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001055
1056 // Now change it back to active and verify we resume sending.
1057 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001058 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1059 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001060}
1061
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001062// Test that SetRtpSendParameters configures the correct encoding channel for
1063// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001064TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1065 SetupForMultiSendStream();
1066 // Create send streams.
1067 for (uint32_t ssrc : kSsrcs4) {
1068 EXPECT_TRUE(
1069 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1070 }
1071 // Configure one stream to be limited by the stream config, another to be
1072 // limited by the global max, and the third one with no per-stream limit
1073 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001074 SetGlobalMaxBitrate(kOpusCodec, 32000);
1075 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1076 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001077 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1078
ossu20a4b3f2017-04-27 02:08:52 -07001079 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1080 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1081 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001082
1083 // Remove the global cap; the streams should switch to their respective
1084 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001085 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001086 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1087 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1088 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001089}
1090
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001091// Test that GetRtpSendParameters returns the currently configured codecs.
1092TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001093 EXPECT_TRUE(SetupSendStream());
1094 cricket::AudioSendParameters parameters;
1095 parameters.codecs.push_back(kIsacCodec);
1096 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001097 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001098
solenberg2100c0b2017-03-01 11:29:29 -08001099 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001100 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001101 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1102 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001103}
1104
deadbeefcb443432016-12-12 11:12:36 -08001105// Test that GetRtpSendParameters returns an SSRC.
1106TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1107 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001108 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001109 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001110 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001111}
1112
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001113// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001114TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001115 EXPECT_TRUE(SetupSendStream());
1116 cricket::AudioSendParameters parameters;
1117 parameters.codecs.push_back(kIsacCodec);
1118 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001119 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001120
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001122
1123 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001124 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001125
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001126 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001127 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1128 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001129}
1130
minyuececec102017-03-27 13:04:25 -07001131// Test that max_bitrate_bps in send stream config gets updated correctly when
1132// SetRtpSendParameters is called.
1133TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1134 webrtc::test::ScopedFieldTrials override_field_trials(
1135 "WebRTC-Audio-SendSideBwe/Enabled/");
1136 EXPECT_TRUE(SetupSendStream());
1137 cricket::AudioSendParameters send_parameters;
1138 send_parameters.codecs.push_back(kOpusCodec);
1139 SetSendParameters(send_parameters);
1140
1141 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1142 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1143 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1144
1145 constexpr int kMaxBitrateBps = 6000;
1146 rtp_parameters.encodings[0].max_bitrate_bps =
1147 rtc::Optional<int>(kMaxBitrateBps);
1148 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1149
1150 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1151 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1152}
1153
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001154// Test that GetRtpReceiveParameters returns the currently configured codecs.
1155TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1156 EXPECT_TRUE(SetupRecvStream());
1157 cricket::AudioRecvParameters parameters;
1158 parameters.codecs.push_back(kIsacCodec);
1159 parameters.codecs.push_back(kPcmuCodec);
1160 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1161
1162 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001163 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1165 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1166 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1167}
1168
deadbeefcb443432016-12-12 11:12:36 -08001169// Test that GetRtpReceiveParameters returns an SSRC.
1170TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1171 EXPECT_TRUE(SetupRecvStream());
1172 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001173 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001174 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001175 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001176}
1177
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001178// Test that if we set/get parameters multiple times, we get the same results.
1179TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1180 EXPECT_TRUE(SetupRecvStream());
1181 cricket::AudioRecvParameters parameters;
1182 parameters.codecs.push_back(kIsacCodec);
1183 parameters.codecs.push_back(kPcmuCodec);
1184 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1185
1186 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001187 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001188
1189 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001190 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001191
1192 // ... And this shouldn't change the params returned by
1193 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001194 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1195 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001196}
1197
deadbeef3bc15102017-04-20 19:25:07 -07001198// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1199// aren't signaled. It should return an empty "RtpEncodingParameters" when
1200// configured to receive an unsignaled stream and no packets have been received
1201// yet, and start returning the SSRC once a packet has been received.
1202TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1203 ASSERT_TRUE(SetupChannel());
1204 // Call necessary methods to configure receiving a default stream as
1205 // soon as it arrives.
1206 cricket::AudioRecvParameters parameters;
1207 parameters.codecs.push_back(kIsacCodec);
1208 parameters.codecs.push_back(kPcmuCodec);
1209 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1210
1211 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1212 // stream. Should return nothing.
1213 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1214
1215 // Set a sink for an unsignaled stream.
1216 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1217 // Value of "0" means "unsignaled stream".
1218 channel_->SetRawAudioSink(0, std::move(fake_sink));
1219
1220 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1221 // in this method means "unsignaled stream".
1222 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1223 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1224 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1225
1226 // Receive PCMU packet (SSRC=1).
1227 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1228
1229 // The |ssrc| member should still be unset.
1230 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1231 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1232 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1233}
1234
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001235// Test that we apply codecs properly.
1236TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001237 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001238 cricket::AudioSendParameters parameters;
1239 parameters.codecs.push_back(kIsacCodec);
1240 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001241 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001242 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001243 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001244 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001245 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1246 EXPECT_EQ(96, send_codec_spec.payload_type);
1247 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1248 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1249 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1250 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001251 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001252}
1253
ossu20a4b3f2017-04-27 02:08:52 -07001254// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1255// AudioSendStream.
1256TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001257 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kIsacCodec);
1260 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001261 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001262 parameters.codecs[0].id = 96;
1263 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001264 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001265 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001266 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001267 // Calling SetSendCodec again with same codec which is already set.
1268 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001269 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001270 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001271}
1272
ossu20a4b3f2017-04-27 02:08:52 -07001273// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1274// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001275
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001276// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001277TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001278 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001279 cricket::AudioSendParameters parameters;
1280 parameters.codecs.push_back(kOpusCodec);
1281 parameters.codecs[0].bitrate = 0;
1282 parameters.codecs[0].clockrate = 50000;
1283 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001286// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001287TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001288 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 cricket::AudioSendParameters parameters;
1290 parameters.codecs.push_back(kOpusCodec);
1291 parameters.codecs[0].bitrate = 0;
1292 parameters.codecs[0].channels = 0;
1293 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001294}
1295
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001296// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001297TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
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(kOpusCodec);
1301 parameters.codecs[0].bitrate = 0;
1302 parameters.codecs[0].channels = 0;
1303 parameters.codecs[0].params["stereo"] = "1";
1304 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305}
1306
1307// Test that if channel is 1 for opus and there's no stereo, we fail.
1308TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001309 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001310 cricket::AudioSendParameters parameters;
1311 parameters.codecs.push_back(kOpusCodec);
1312 parameters.codecs[0].bitrate = 0;
1313 parameters.codecs[0].channels = 1;
1314 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001315}
1316
1317// Test that if channel is 1 for opus and stereo=0, we fail.
1318TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001319 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001320 cricket::AudioSendParameters parameters;
1321 parameters.codecs.push_back(kOpusCodec);
1322 parameters.codecs[0].bitrate = 0;
1323 parameters.codecs[0].channels = 1;
1324 parameters.codecs[0].params["stereo"] = "0";
1325 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326}
1327
1328// Test that if channel is 1 for opus and stereo=1, we fail.
1329TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001330 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001331 cricket::AudioSendParameters parameters;
1332 parameters.codecs.push_back(kOpusCodec);
1333 parameters.codecs[0].bitrate = 0;
1334 parameters.codecs[0].channels = 1;
1335 parameters.codecs[0].params["stereo"] = "1";
1336 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337}
1338
ossu20a4b3f2017-04-27 02:08:52 -07001339// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001341 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 cricket::AudioSendParameters parameters;
1343 parameters.codecs.push_back(kOpusCodec);
1344 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001345 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001346 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347}
1348
ossu20a4b3f2017-04-27 02:08:52 -07001349// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001351 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001352 cricket::AudioSendParameters parameters;
1353 parameters.codecs.push_back(kOpusCodec);
1354 parameters.codecs[0].bitrate = 0;
1355 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001356 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001357 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358}
1359
ossu20a4b3f2017-04-27 02:08:52 -07001360// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001361TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001362 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 cricket::AudioSendParameters parameters;
1364 parameters.codecs.push_back(kOpusCodec);
1365 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001366 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001368 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001369 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001370
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001372 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001373 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001374}
1375
ossu20a4b3f2017-04-27 02:08:52 -07001376// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001378 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001379 cricket::AudioSendParameters parameters;
1380 parameters.codecs.push_back(kOpusCodec);
1381 parameters.codecs[0].bitrate = 0;
1382 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001383 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001384 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385}
1386
ossu20a4b3f2017-04-27 02:08:52 -07001387// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001388TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001389 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 cricket::AudioSendParameters parameters;
1391 parameters.codecs.push_back(kOpusCodec);
1392 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001393 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001396 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001399 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001400 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001401}
1402
ossu20a4b3f2017-04-27 02:08:52 -07001403// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001405 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001406 cricket::AudioSendParameters parameters;
1407 parameters.codecs.push_back(kOpusCodec);
1408 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001409 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001410 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1411 EXPECT_EQ(111, spec.payload_type);
1412 EXPECT_EQ(96000, spec.target_bitrate_bps);
1413 EXPECT_EQ("opus", spec.format.name);
1414 EXPECT_EQ(2, spec.format.num_channels);
1415 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416}
1417
ossu20a4b3f2017-04-27 02:08:52 -07001418// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 30000;
1424 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001427}
1428
ossu20a4b3f2017-04-27 02:08:52 -07001429// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001430TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001431 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001432 cricket::AudioSendParameters parameters;
1433 parameters.codecs.push_back(kOpusCodec);
1434 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001435 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001436 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001437}
1438
ossu20a4b3f2017-04-27 02:08:52 -07001439// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001441 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 cricket::AudioSendParameters parameters;
1443 parameters.codecs.push_back(kOpusCodec);
1444 parameters.codecs[0].bitrate = 30000;
1445 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001448}
1449
stefan13f1a0a2016-11-30 07:22:58 -08001450TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1451 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1452 200000);
1453}
1454
1455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1456 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1457}
1458
1459TEST_F(WebRtcVoiceEngineTestFake,
1460 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1461 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1462}
1463
1464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1465 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1466}
1467
1468TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001469 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001470 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1471 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001472 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001473 SetSendParameters(send_parameters_);
1474 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1475 << "Setting max bitrate should keep previous min bitrate.";
1476 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1477 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001478 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001479}
1480
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001481// Test that we can enable NACK with opus as caller.
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001483 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001484 cricket::AudioSendParameters parameters;
1485 parameters.codecs.push_back(kOpusCodec);
1486 parameters.codecs[0].AddFeedbackParam(
1487 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1488 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001489 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001490 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001491 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001492}
1493
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001494// Test that we can enable NACK with opus as callee.
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001496 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001497 cricket::AudioSendParameters parameters;
1498 parameters.codecs.push_back(kOpusCodec);
1499 parameters.codecs[0].AddFeedbackParam(
1500 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1501 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001502 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001503 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001504 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001505 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001506
1507 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001508 cricket::StreamParams::CreateLegacy(kSsrcX)));
1509 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001510}
1511
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512// Test that we can enable NACK on receive streams.
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001514 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001515 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001516 cricket::AudioSendParameters parameters;
1517 parameters.codecs.push_back(kOpusCodec);
1518 parameters.codecs[0].AddFeedbackParam(
1519 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1520 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1522 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001524 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1525 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001526}
1527
1528// Test that we can disable NACK.
1529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001530 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 cricket::AudioSendParameters parameters;
1532 parameters.codecs.push_back(kOpusCodec);
1533 parameters.codecs[0].AddFeedbackParam(
1534 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1535 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001536 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001538
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001539 parameters.codecs.clear();
1540 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543}
1544
1545// Test that we can disable NACK on receive streams.
1546TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001547 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001548 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001549 cricket::AudioSendParameters parameters;
1550 parameters.codecs.push_back(kOpusCodec);
1551 parameters.codecs[0].AddFeedbackParam(
1552 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1553 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001554 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1556 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001557
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001558 parameters.codecs.clear();
1559 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1562 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563}
1564
1565// Test that NACK is enabled on a new receive stream.
1566TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001567 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001568 cricket::AudioSendParameters parameters;
1569 parameters.codecs.push_back(kIsacCodec);
1570 parameters.codecs.push_back(kCn16000Codec);
1571 parameters.codecs[0].AddFeedbackParam(
1572 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1573 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001574 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_TRUE(AddRecvStream(kSsrcY));
1578 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1579 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1580 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001581}
1582
stefanba4c0e42016-02-04 04:12:24 -08001583TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001584 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001585 cricket::AudioSendParameters send_parameters;
1586 send_parameters.codecs.push_back(kOpusCodec);
1587 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001588 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001589
1590 cricket::AudioRecvParameters recv_parameters;
1591 recv_parameters.codecs.push_back(kIsacCodec);
1592 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001593 EXPECT_TRUE(AddRecvStream(kSsrcX));
1594 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001595 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001596 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001597
ossudedfd282016-06-14 07:12:39 -07001598 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001599 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001600 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001601 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001602 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001603}
1604
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001605// Test that we can switch back and forth between Opus and ISAC with CN.
1606TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001608
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001609 cricket::AudioSendParameters opus_parameters;
1610 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001611 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001612 {
ossu20a4b3f2017-04-27 02:08:52 -07001613 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1614 EXPECT_EQ(111, spec.payload_type);
1615 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001616 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001618 cricket::AudioSendParameters isac_parameters;
1619 isac_parameters.codecs.push_back(kIsacCodec);
1620 isac_parameters.codecs.push_back(kCn16000Codec);
1621 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001623 {
ossu20a4b3f2017-04-27 02:08:52 -07001624 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1625 EXPECT_EQ(103, spec.payload_type);
1626 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001627 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001628
solenberg059fb442016-10-26 05:12:24 -07001629 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001630 {
ossu20a4b3f2017-04-27 02:08:52 -07001631 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1632 EXPECT_EQ(111, spec.payload_type);
1633 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001634 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001635}
1636
1637// Test that we handle various ways of specifying bitrate.
1638TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001639 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001640 cricket::AudioSendParameters parameters;
1641 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001642 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001643 {
ossu20a4b3f2017-04-27 02:08:52 -07001644 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1645 EXPECT_EQ(103, spec.payload_type);
1646 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1647 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001648 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001649
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001650 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001651 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001652 {
ossu20a4b3f2017-04-27 02:08:52 -07001653 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1654 EXPECT_EQ(103, spec.payload_type);
1655 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1656 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001657 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001660 {
ossu20a4b3f2017-04-27 02:08:52 -07001661 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1662 EXPECT_EQ(103, spec.payload_type);
1663 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1664 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001665 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001668 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001669 {
ossu20a4b3f2017-04-27 02:08:52 -07001670 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1671 EXPECT_EQ(0, spec.payload_type);
1672 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1673 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001674 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001678 {
ossu20a4b3f2017-04-27 02:08:52 -07001679 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1680 EXPECT_EQ(0, spec.payload_type);
1681 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1682 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 parameters.codecs[0] = kOpusCodec;
1686 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001688 {
ossu20a4b3f2017-04-27 02:08:52 -07001689 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1690 EXPECT_EQ(111, spec.payload_type);
1691 EXPECT_STREQ("opus", spec.format.name.c_str());
1692 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001693 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001694}
1695
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001696// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001698 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 cricket::AudioSendParameters parameters;
1700 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001701}
1702
1703// Test that we can set send codecs even with telephone-event codec as the first
1704// one on the list.
1705TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001706 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001707 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001708 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001709 parameters.codecs.push_back(kIsacCodec);
1710 parameters.codecs.push_back(kPcmuCodec);
1711 parameters.codecs[0].id = 98; // DTMF
1712 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001714 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1715 EXPECT_EQ(96, spec.payload_type);
1716 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001717 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001718}
1719
solenberg31642aa2016-03-14 08:00:37 -07001720// Test that payload type range is limited for telephone-event codec.
1721TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001722 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001723 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001724 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001725 parameters.codecs.push_back(kIsacCodec);
1726 parameters.codecs[0].id = 0; // DTMF
1727 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001728 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001729 EXPECT_TRUE(channel_->CanInsertDtmf());
1730 parameters.codecs[0].id = 128; // DTMF
1731 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1732 EXPECT_FALSE(channel_->CanInsertDtmf());
1733 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001735 EXPECT_TRUE(channel_->CanInsertDtmf());
1736 parameters.codecs[0].id = -1; // DTMF
1737 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1738 EXPECT_FALSE(channel_->CanInsertDtmf());
1739}
1740
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001741// Test that we can set send codecs even with CN codec as the first
1742// one on the list.
1743TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001744 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 cricket::AudioSendParameters parameters;
1746 parameters.codecs.push_back(kCn16000Codec);
1747 parameters.codecs.push_back(kIsacCodec);
1748 parameters.codecs.push_back(kPcmuCodec);
1749 parameters.codecs[0].id = 98; // wideband CN
1750 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001752 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1753 EXPECT_EQ(96, send_codec_spec.payload_type);
1754 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001755 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756}
1757
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001758// Test that we set VAD and DTMF types correctly as caller.
1759TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001760 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001761 cricket::AudioSendParameters parameters;
1762 parameters.codecs.push_back(kIsacCodec);
1763 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 parameters.codecs.push_back(kCn16000Codec);
1766 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001767 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001768 parameters.codecs[0].id = 96;
1769 parameters.codecs[2].id = 97; // wideband CN
1770 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001771 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001772 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1773 EXPECT_EQ(96, send_codec_spec.payload_type);
1774 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1775 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001776 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001777 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778}
1779
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001780// Test that we set VAD and DTMF types correctly as callee.
1781TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001782 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001783 cricket::AudioSendParameters parameters;
1784 parameters.codecs.push_back(kIsacCodec);
1785 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001786 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 parameters.codecs.push_back(kCn16000Codec);
1788 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001789 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001790 parameters.codecs[0].id = 96;
1791 parameters.codecs[2].id = 97; // wideband CN
1792 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001794 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001795 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001796
ossu20a4b3f2017-04-27 02:08:52 -07001797 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1798 EXPECT_EQ(96, send_codec_spec.payload_type);
1799 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1800 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001801 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001802 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001803}
1804
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001805// Test that we only apply VAD if we have a CN codec that matches the
1806// send codec clockrate.
1807TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001808 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001809 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 parameters.codecs.push_back(kIsacCodec);
1812 parameters.codecs.push_back(kCn16000Codec);
1813 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001814 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001815 {
ossu20a4b3f2017-04-27 02:08:52 -07001816 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1817 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1818 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001819 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001820 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001821 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001823 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001824 {
ossu20a4b3f2017-04-27 02:08:52 -07001825 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1826 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1827 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001828 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001830 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001831 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001832 {
ossu20a4b3f2017-04-27 02:08:52 -07001833 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1834 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1835 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001837 }
Brave Yao5225dd82015-03-26 07:39:19 +08001838 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001839 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001841 {
ossu20a4b3f2017-04-27 02:08:52 -07001842 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1843 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1844 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001845 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001846}
1847
1848// Test that we perform case-insensitive matching of codec names.
1849TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001850 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001851 cricket::AudioSendParameters parameters;
1852 parameters.codecs.push_back(kIsacCodec);
1853 parameters.codecs.push_back(kPcmuCodec);
1854 parameters.codecs.push_back(kCn16000Codec);
1855 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001856 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001857 parameters.codecs[0].name = "iSaC";
1858 parameters.codecs[0].id = 96;
1859 parameters.codecs[2].id = 97; // wideband CN
1860 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001861 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001862 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1863 EXPECT_EQ(96, send_codec_spec.payload_type);
1864 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1865 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001866 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001867 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001868}
1869
stefanba4c0e42016-02-04 04:12:24 -08001870class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1871 public:
1872 WebRtcVoiceEngineWithSendSideBweTest()
1873 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1874};
1875
1876TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1877 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001878 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001879 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001880 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1881 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1882 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001883 extension.id);
1884 return;
1885 }
1886 }
1887 FAIL() << "Transport sequence number extension not in header-extension list.";
1888}
1889
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001890// Test support for audio level header extension.
1891TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001892 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001893}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001894TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001895 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001896}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001897
solenbergd4adce42016-11-17 06:26:52 -08001898// Test support for transport sequence number header extension.
1899TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1900 TestSetSendRtpHeaderExtensions(
1901 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001902}
solenbergd4adce42016-11-17 06:26:52 -08001903TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1904 TestSetRecvRtpHeaderExtensions(
1905 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001906}
1907
solenberg1ac56142015-10-13 03:58:19 -07001908// Test that we can create a channel and start sending on it.
1909TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001910 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(send_parameters_);
1912 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001913 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001914 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001915 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001916}
1917
1918// Test that a channel will send if and only if it has a source and is enabled
1919// for sending.
1920TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001921 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001922 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001923 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001924 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001925 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1926 SetAudioSend(kSsrcX, true, &fake_source_);
1927 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1928 SetAudioSend(kSsrcX, true, nullptr);
1929 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001930}
1931
solenberg94218532016-06-16 10:53:22 -07001932// Test that a channel is muted/unmuted.
1933TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1934 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001935 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001936 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1937 SetAudioSend(kSsrcX, true, nullptr);
1938 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1939 SetAudioSend(kSsrcX, false, nullptr);
1940 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001941}
1942
solenberg6d6e7c52016-04-13 09:07:30 -07001943// Test that SetSendParameters() does not alter a stream's send state.
1944TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1945 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001946 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001947
1948 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001949 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001950 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001951
1952 // Changing RTP header extensions will recreate the AudioSendStream.
1953 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001954 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001955 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001956 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001957
1958 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001959 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001960 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001961
1962 // Changing RTP header extensions will recreate the AudioSendStream.
1963 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001964 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001965 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001966}
1967
solenberg1ac56142015-10-13 03:58:19 -07001968// Test that we can create a channel and start playing out on it.
1969TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001970 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001971 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001972 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001973 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001974 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001975 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976}
1977
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001978// Test that we can add and remove send streams.
1979TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1980 SetupForMultiSendStream();
1981
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001982 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001983 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001984
solenbergc96df772015-10-21 13:01:53 -07001985 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001986 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001987 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001988 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001989 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001990 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001991 }
tfarina5237aaf2015-11-10 23:44:30 -08001992 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001993
solenbergc96df772015-10-21 13:01:53 -07001994 // Delete the send streams.
1995 for (uint32_t ssrc : kSsrcs4) {
1996 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001997 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001998 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001999 }
solenbergc96df772015-10-21 13:01:53 -07002000 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002001}
2002
2003// Test SetSendCodecs correctly configure the codecs in all send streams.
2004TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2005 SetupForMultiSendStream();
2006
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002007 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002008 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002009 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002010 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002011 }
2012
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002013 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002015 parameters.codecs.push_back(kIsacCodec);
2016 parameters.codecs.push_back(kCn16000Codec);
2017 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002018 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019
2020 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002021 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002022 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2023 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002024 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2025 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2026 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002027 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002028 }
2029
minyue7a973442016-10-20 03:27:12 -07002030 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002031 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002032 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002033 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002034 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2035 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002036 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2037 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2038 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002039 }
2040}
2041
2042// Test we can SetSend on all send streams correctly.
2043TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2044 SetupForMultiSendStream();
2045
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002046 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002047 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002049 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002050 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002051 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 }
2053
2054 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002055 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002056 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002057 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002058 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 }
2060
2061 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002062 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002063 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002064 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002065 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002066 }
2067}
2068
2069// Test we can set the correct statistics on all send streams.
2070TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2071 SetupForMultiSendStream();
2072
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002074 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002076 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002077 }
solenberg85a04962015-10-27 03:35:21 -07002078
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002079 // Create a receive stream to check that none of the send streams end up in
2080 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002081 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002082
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002084 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002085 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002086 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087
solenberg85a04962015-10-27 03:35:21 -07002088 // Check stats for the added streams.
2089 {
2090 cricket::VoiceMediaInfo info;
2091 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002092
solenberg85a04962015-10-27 03:35:21 -07002093 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002094 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002095 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002096 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002097 }
hbos1acfbd22016-11-17 23:43:29 -08002098 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002099
2100 // We have added one receive stream. We should see empty stats.
2101 EXPECT_EQ(info.receivers.size(), 1u);
2102 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 }
solenberg1ac56142015-10-13 03:58:19 -07002104
solenberg2100c0b2017-03-01 11:29:29 -08002105 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002106 {
2107 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002108 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002109 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002110 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002111 EXPECT_EQ(0u, info.receivers.size());
2112 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002113
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002114 // Deliver a new packet - a default receive stream should be created and we
2115 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002116 {
2117 cricket::VoiceMediaInfo info;
2118 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2119 SetAudioReceiveStreamStats();
2120 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002121 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002122 EXPECT_EQ(1u, info.receivers.size());
2123 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002124 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002125 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002126}
2127
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128// Test that we can add and remove receive streams, and do proper send/playout.
2129// We can receive on multiple streams while sending one stream.
2130TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002131 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132
solenberg1ac56142015-10-13 03:58:19 -07002133 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002134 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002135 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002136
solenberg1ac56142015-10-13 03:58:19 -07002137 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002138 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002139 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002140 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002141
solenberg1ac56142015-10-13 03:58:19 -07002142 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002143 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002144
2145 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002146 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2147 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2148 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002149
2150 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002151 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002152 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153
2154 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002155 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002156 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2157 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158
aleloi84ef6152016-08-04 05:28:21 -07002159 // Restart playout and make sure recv streams are played out.
2160 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002161 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2162 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002163
aleloi84ef6152016-08-04 05:28:21 -07002164 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002165 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2166 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167}
2168
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002170// and start sending on it.
2171TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002172 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002173 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2174 EXPECT_CALL(apm_gc_,
2175 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002176 SetSendParameters(send_parameters_);
2177 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002178 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002179 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002180 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181}
2182
wu@webrtc.org97077a32013-10-25 21:18:33 +00002183TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002184 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002185 EXPECT_CALL(adm_,
2186 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002187 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2188 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002189 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2190 send_parameters_.options.tx_agc_digital_compression_gain =
2191 rtc::Optional<uint16_t>(9);
2192 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2193 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002194 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2195 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2196 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002197 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002198
2199 // Check interaction with adjust_agc_delta. Both should be respected, for
2200 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002201 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002202 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002203 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002204}
2205
wu@webrtc.org97077a32013-10-25 21:18:33 +00002206TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002207 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002208 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2209 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002210 send_parameters_.options.recording_sample_rate =
2211 rtc::Optional<uint32_t>(48000);
2212 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002213 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002214}
2215
minyue6b825df2016-10-31 04:08:32 -07002216TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2217 EXPECT_TRUE(SetupSendStream());
2218 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2219 send_parameters_.options.audio_network_adaptor_config =
2220 rtc::Optional<std::string>("1234");
2221 SetSendParameters(send_parameters_);
2222 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002223 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002224}
2225
2226TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2227 EXPECT_TRUE(SetupSendStream());
2228 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2229 send_parameters_.options.audio_network_adaptor_config =
2230 rtc::Optional<std::string>("1234");
2231 SetSendParameters(send_parameters_);
2232 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002233 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002234 cricket::AudioOptions options;
2235 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002236 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002237 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002238}
2239
2240TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2241 EXPECT_TRUE(SetupSendStream());
2242 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2243 send_parameters_.options.audio_network_adaptor_config =
2244 rtc::Optional<std::string>("1234");
2245 SetSendParameters(send_parameters_);
2246 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002247 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002248 const int initial_num = call_.GetNumCreatedSendStreams();
2249 cricket::AudioOptions options;
2250 options.audio_network_adaptor = rtc::Optional<bool>();
2251 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2252 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002253 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002254 // AudioSendStream not expected to be recreated.
2255 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2256 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002257 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002258}
2259
michaelt6672b262017-01-11 10:17:59 -08002260class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2261 : public WebRtcVoiceEngineTestFake {
2262 public:
2263 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2264 : WebRtcVoiceEngineTestFake(
2265 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2266 "Enabled/") {}
2267};
2268
2269TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2270 EXPECT_TRUE(SetupSendStream());
2271 cricket::AudioSendParameters parameters;
2272 parameters.codecs.push_back(kOpusCodec);
2273 SetSendParameters(parameters);
2274 const int initial_num = call_.GetNumCreatedSendStreams();
2275 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2276
2277 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2278 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002279 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2280 constexpr int kMinOverheadBps =
2281 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002282
2283 constexpr int kOpusMinBitrateBps = 6000;
2284 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002285 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002286 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002287 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002288 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002289
2290 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2291 parameters.options.audio_network_adaptor_config =
2292 rtc::Optional<std::string>("1234");
2293 SetSendParameters(parameters);
2294
ossu11bfc532017-02-16 05:37:06 -08002295 constexpr int kMinOverheadWithAnaBps =
2296 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002297
2298 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002299 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002300
minyuececec102017-03-27 13:04:25 -07002301 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002302 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002303}
2304
minyuececec102017-03-27 13:04:25 -07002305// This test is similar to
2306// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2307// additional field trial.
2308TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2309 SetRtpSendParameterUpdatesMaxBitrate) {
2310 EXPECT_TRUE(SetupSendStream());
2311 cricket::AudioSendParameters send_parameters;
2312 send_parameters.codecs.push_back(kOpusCodec);
2313 SetSendParameters(send_parameters);
2314
2315 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2316 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2317 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2318
2319 constexpr int kMaxBitrateBps = 6000;
2320 rtp_parameters.encodings[0].max_bitrate_bps =
2321 rtc::Optional<int>(kMaxBitrateBps);
2322 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2323
2324 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2325#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2326 constexpr int kMinOverhead = 3333;
2327#else
2328 constexpr int kMinOverhead = 6666;
2329#endif
2330 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2331}
2332
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002333// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002334// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002335TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002336 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002337 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002338}
2339
2340TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2341 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002342 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002343 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002344 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002345 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002346 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002347 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002348 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349
solenberg85a04962015-10-27 03:35:21 -07002350 // Check stats for the added streams.
2351 {
2352 cricket::VoiceMediaInfo info;
2353 EXPECT_EQ(true, channel_->GetStats(&info));
2354
2355 // We have added one send stream. We should see the stats we've set.
2356 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002357 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002358 // We have added one receive stream. We should see empty stats.
2359 EXPECT_EQ(info.receivers.size(), 1u);
2360 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2361 }
solenberg1ac56142015-10-13 03:58:19 -07002362
solenberg566ef242015-11-06 15:34:49 -08002363 // Start sending - this affects some reported stats.
2364 {
2365 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002366 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002367 EXPECT_EQ(true, channel_->GetStats(&info));
2368 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002369 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002370 }
2371
solenberg2100c0b2017-03-01 11:29:29 -08002372 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002373 {
2374 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002375 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002376 EXPECT_EQ(true, channel_->GetStats(&info));
2377 EXPECT_EQ(1u, info.senders.size());
2378 EXPECT_EQ(0u, info.receivers.size());
2379 }
solenberg1ac56142015-10-13 03:58:19 -07002380
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002381 // Deliver a new packet - a default receive stream should be created and we
2382 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002383 {
2384 cricket::VoiceMediaInfo info;
2385 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2386 SetAudioReceiveStreamStats();
2387 EXPECT_EQ(true, channel_->GetStats(&info));
2388 EXPECT_EQ(1u, info.senders.size());
2389 EXPECT_EQ(1u, info.receivers.size());
2390 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002391 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002392 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002393}
2394
2395// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002396// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002398 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002399 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2400 EXPECT_TRUE(AddRecvStream(kSsrcY));
2401 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002402}
2403
2404// Test that the local SSRC is the same on sending and receiving channels if the
2405// receive channel is created before the send channel.
2406TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002407 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002408 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002410 cricket::StreamParams::CreateLegacy(kSsrcX)));
2411 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2412 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413}
2414
2415// Test that we can properly receive packets.
2416TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002417 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002418 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002420
2421 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2422 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423}
2424
2425// Test that we can properly receive packets on multiple streams.
2426TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002427 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002428 const uint32_t ssrc1 = 1;
2429 const uint32_t ssrc2 = 2;
2430 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002431 EXPECT_TRUE(AddRecvStream(ssrc1));
2432 EXPECT_TRUE(AddRecvStream(ssrc2));
2433 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002435 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002436 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002437 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002438 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439 }
mflodman3d7db262016-04-29 00:57:13 -07002440
2441 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2442 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2443 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2444
2445 EXPECT_EQ(s1.received_packets(), 0);
2446 EXPECT_EQ(s2.received_packets(), 0);
2447 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002448
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002450 EXPECT_EQ(s1.received_packets(), 0);
2451 EXPECT_EQ(s2.received_packets(), 0);
2452 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002453
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002455 EXPECT_EQ(s1.received_packets(), 1);
2456 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2457 EXPECT_EQ(s2.received_packets(), 0);
2458 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002459
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002461 EXPECT_EQ(s1.received_packets(), 1);
2462 EXPECT_EQ(s2.received_packets(), 1);
2463 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2464 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002465
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002467 EXPECT_EQ(s1.received_packets(), 1);
2468 EXPECT_EQ(s2.received_packets(), 1);
2469 EXPECT_EQ(s3.received_packets(), 1);
2470 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002471
mflodman3d7db262016-04-29 00:57:13 -07002472 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2473 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2474 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475}
2476
solenberg2100c0b2017-03-01 11:29:29 -08002477// Test that receiving on an unsignaled stream works (a stream is created).
2478TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002479 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002480 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2481
solenberg7e63ef02015-11-20 00:19:43 -08002482 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002483
2484 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002485 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2486 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002487}
2488
solenberg2100c0b2017-03-01 11:29:29 -08002489// Test that receiving N unsignaled stream works (streams will be created), and
2490// that packets are forwarded to them all.
2491TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002492 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002493 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002494 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2495
solenberg2100c0b2017-03-01 11:29:29 -08002496 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002497 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002498 rtc::SetBE32(&packet[8], ssrc);
2499 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002500
solenberg2100c0b2017-03-01 11:29:29 -08002501 // Verify we have one new stream for each loop iteration.
2502 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002503 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2504 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002505 }
mflodman3d7db262016-04-29 00:57:13 -07002506
solenberg2100c0b2017-03-01 11:29:29 -08002507 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002508 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002509 rtc::SetBE32(&packet[8], ssrc);
2510 DeliverPacket(packet, sizeof(packet));
2511
solenbergebb349d2017-03-13 05:46:15 -07002512 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002513 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2514 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2515 }
2516
2517 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2518 constexpr uint32_t kAnotherSsrc = 667;
2519 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002520 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002521
2522 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002523 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002524 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002525 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002526 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2527 EXPECT_EQ(2, streams[i]->received_packets());
2528 }
2529 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2530 EXPECT_EQ(1, streams[i]->received_packets());
2531 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002532 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002533}
2534
solenberg2100c0b2017-03-01 11:29:29 -08002535// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002536// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002537TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002538 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002539 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002540 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2541
2542 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002543 const uint32_t signaled_ssrc = 1;
2544 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002545 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002546 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002547 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2548 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002549 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002550
2551 // Note that the first unknown SSRC cannot be 0, because we only support
2552 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002553 const uint32_t unsignaled_ssrc = 7011;
2554 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002555 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002556 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2557 packet, sizeof(packet)));
2558 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2559
2560 DeliverPacket(packet, sizeof(packet));
2561 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2562
2563 rtc::SetBE32(&packet[8], signaled_ssrc);
2564 DeliverPacket(packet, sizeof(packet));
2565 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2566 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002567}
2568
solenberg4904fb62017-02-17 12:01:14 -08002569// Two tests to verify that adding a receive stream with the same SSRC as a
2570// previously added unsignaled stream will only recreate underlying stream
2571// objects if the stream parameters have changed.
2572TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2573 EXPECT_TRUE(SetupChannel());
2574
2575 // Spawn unsignaled stream with SSRC=1.
2576 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2577 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2578 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2579 sizeof(kPcmuFrame)));
2580
2581 // Verify that the underlying stream object in Call is not recreated when a
2582 // stream with SSRC=1 is added.
2583 const auto& streams = call_.GetAudioReceiveStreams();
2584 EXPECT_EQ(1, streams.size());
2585 int audio_receive_stream_id = streams.front()->id();
2586 EXPECT_TRUE(AddRecvStream(1));
2587 EXPECT_EQ(1, streams.size());
2588 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2589}
2590
2591TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2592 EXPECT_TRUE(SetupChannel());
2593
2594 // Spawn unsignaled stream with SSRC=1.
2595 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2596 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2597 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2598 sizeof(kPcmuFrame)));
2599
2600 // Verify that the underlying stream object in Call *is* recreated when a
2601 // stream with SSRC=1 is added, and which has changed stream parameters.
2602 const auto& streams = call_.GetAudioReceiveStreams();
2603 EXPECT_EQ(1, streams.size());
2604 int audio_receive_stream_id = streams.front()->id();
2605 cricket::StreamParams stream_params;
2606 stream_params.ssrcs.push_back(1);
2607 stream_params.sync_label = "sync_label";
2608 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2609 EXPECT_EQ(1, streams.size());
2610 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2611}
2612
solenberg0a617e22015-10-20 15:49:38 -07002613// Test that we properly handle failures to add a receive stream.
2614TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002615 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002616 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002617 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002618}
2619
solenberg0a617e22015-10-20 15:49:38 -07002620// Test that we properly handle failures to add a send stream.
2621TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002622 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002623 voe_.set_fail_create_channel(true);
2624 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2625}
2626
solenberg1ac56142015-10-13 03:58:19 -07002627// Test that AddRecvStream creates new stream.
2628TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002629 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002630 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002631 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002632 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002633}
2634
2635// Test that after adding a recv stream, we do not decode more codecs than
2636// those previously passed into SetRecvCodecs.
2637TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002638 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002639 cricket::AudioRecvParameters parameters;
2640 parameters.codecs.push_back(kIsacCodec);
2641 parameters.codecs.push_back(kPcmuCodec);
2642 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002643 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002644 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2645 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2646 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002647}
2648
2649// Test that we properly clean up any streams that were added, even if
2650// not explicitly removed.
2651TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002653 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002654 EXPECT_TRUE(AddRecvStream(1));
2655 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002656 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2657 delete channel_;
2658 channel_ = NULL;
2659 EXPECT_EQ(0, voe_.GetNumChannels());
2660}
2661
wu@webrtc.org78187522013-10-07 23:32:02 +00002662TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002664 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002665}
2666
2667TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002668 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002669 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002670 // Manually delete channel to simulate a failure.
2671 int channel = voe_.GetLastChannel();
2672 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2673 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002674 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002675 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002676 EXPECT_NE(channel, new_channel);
2677 // The last created channel is deleted too.
2678 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002679}
2680
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002681// Test the InsertDtmf on default send stream as caller.
2682TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002683 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002684}
2685
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002686// Test the InsertDtmf on default send stream as callee
2687TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002688 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002689}
2690
2691// Test the InsertDtmf on specified send stream as caller.
2692TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002693 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002694}
2695
2696// Test the InsertDtmf on specified send stream as callee.
2697TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002698 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699}
2700
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002701TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002702 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002703 EXPECT_CALL(adm_,
2704 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2705 EXPECT_CALL(adm_,
2706 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2707 EXPECT_CALL(adm_,
2708 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002709
solenberg246b8172015-12-08 09:50:23 -08002710 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2711 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002712
solenberg246b8172015-12-08 09:50:23 -08002713 // Nothing set in AudioOptions, so everything should be as default.
2714 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002715 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002716 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002717 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2718 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719
2720 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002721 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2722 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002723 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002724 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725
2726 // Turn echo cancellation back on, with settings, and make sure
2727 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002728 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2729 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002730 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002731 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002733 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2734 // control.
solenberg76377c52017-02-21 00:54:31 -08002735 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2736 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002737 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002738 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002739
2740 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002741 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002743 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2744 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2745 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002746 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002747
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002748 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002749 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2750 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002751 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002753
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2757 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2758 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002759 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002761
2762 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002763 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2765 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2766 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002767 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2768 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002769 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770
2771 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002772 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2774 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2775 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2778 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002779 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2780 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2781 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2782 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002783 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002784 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785
solenberg1ac56142015-10-13 03:58:19 -07002786 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002787 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2789 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2793 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002794 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795}
2796
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002798 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002799 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002800 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002801 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002802 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002803 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002804 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002805 EXPECT_CALL(adm_,
2806 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2807 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2808 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002809 webrtc::AudioProcessing::Config apm_config;
2810 EXPECT_CALL(*apm_, GetConfig())
2811 .Times(10)
2812 .WillRepeatedly(ReturnPointee(&apm_config));
2813 EXPECT_CALL(*apm_, ApplyConfig(_))
2814 .Times(10)
2815 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002816 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002817
kwiberg686a8ef2016-02-26 03:00:35 -08002818 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002819 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002820 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002821 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002822 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002823 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002824
2825 // Have to add a stream to make SetSend work.
2826 cricket::StreamParams stream1;
2827 stream1.ssrcs.push_back(1);
2828 channel1->AddSendStream(stream1);
2829 cricket::StreamParams stream2;
2830 stream2.ssrcs.push_back(2);
2831 channel2->AddSendStream(stream2);
2832
2833 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002834 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002835 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2836 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2837 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002838 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2839 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2840 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2841 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2842 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002843 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002844 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002845 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002846 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002847
2848 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002849 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002850 parameters_options_no_ns.options.noise_suppression =
2851 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002852 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2853 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2854 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2855 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2856 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002857 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002858 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002859 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2860 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2861 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002862 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863
2864 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002865 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002866 parameters_options_no_agc.options.auto_gain_control =
2867 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002868 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2872 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002873 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002874 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2875 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2876 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002877 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002878
solenberg76377c52017-02-21 00:54:31 -08002879 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2880 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2881 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2882 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2883 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002884 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002885
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002891 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002892
solenberg76377c52017-02-21 00:54:31 -08002893 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2897 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002898 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002899
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002901 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2902 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002903 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002904 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002905 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002906 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002907 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2908 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2909 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2910 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2911 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002912 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002913 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2914 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2915 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002916 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917}
2918
wu@webrtc.orgde305012013-10-31 15:40:38 +00002919// This test verifies DSCP settings are properly applied on voice media channel.
2920TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002921 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002922 cricket::FakeNetworkInterface network_interface;
2923 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002924 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002925
peahb1c9d1d2017-07-25 15:45:24 -07002926 webrtc::AudioProcessing::Config apm_config;
2927 EXPECT_CALL(*apm_, GetConfig())
2928 .Times(3)
2929 .WillRepeatedly(ReturnPointee(&apm_config));
2930 EXPECT_CALL(*apm_, ApplyConfig(_))
2931 .Times(3)
2932 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002933 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002934
solenbergbc37fc82016-04-04 09:54:44 -07002935 channel.reset(
2936 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002937 channel->SetInterface(&network_interface);
2938 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2939 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2940
2941 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002942 channel.reset(
2943 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002944 channel->SetInterface(&network_interface);
2945 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2946
2947 // Verify that setting the option to false resets the
2948 // DiffServCodePoint.
2949 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002950 channel.reset(
2951 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002952 channel->SetInterface(&network_interface);
2953 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2954 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2955
2956 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002957}
2958
solenberg1ac56142015-10-13 03:58:19 -07002959TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002960 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961 cricket::WebRtcVoiceMediaChannel* media_channel =
2962 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002963 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002964 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002965 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002966 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2967 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2968 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002969 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002970 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971}
2972
solenberg1ac56142015-10-13 03:58:19 -07002973TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002974 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002976 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2977 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2978 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002979 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002980 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002981 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2982 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002983 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002984 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002985 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002986 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987}
2988
solenberg4bac9c52015-10-09 02:32:53 -07002989TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002990 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002991 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002992 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002993 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002994 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002995 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2996 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2997 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002998}
2999
solenberg2100c0b2017-03-01 11:29:29 -08003000TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003001 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003002
3003 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003004 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003005 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3006
3007 // Should remember the volume "2" which will be set on new unsignaled streams,
3008 // and also set the gain to 2 on existing unsignaled streams.
3009 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3010 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3011
3012 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3013 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3014 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3015 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3016 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3017 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3018
3019 // Setting gain with SSRC=0 should affect all unsignaled streams.
3020 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003021 if (kMaxUnsignaledRecvStreams > 1) {
3022 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3023 }
solenberg2100c0b2017-03-01 11:29:29 -08003024 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3025
3026 // Setting gain on an individual stream affects only that.
3027 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003028 if (kMaxUnsignaledRecvStreams > 1) {
3029 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3030 }
solenberg2100c0b2017-03-01 11:29:29 -08003031 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032}
3033
pbos8fc7fa72015-07-15 08:02:58 -07003034TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003035 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003036 const std::string kSyncLabel = "AvSyncLabel";
3037
solenbergff976312016-03-30 23:28:51 -07003038 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003039 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3040 sp.sync_label = kSyncLabel;
3041 // Creating two channels to make sure that sync label is set properly for both
3042 // the default voice channel and following ones.
3043 EXPECT_TRUE(channel_->AddRecvStream(sp));
3044 sp.ssrcs[0] += 1;
3045 EXPECT_TRUE(channel_->AddRecvStream(sp));
3046
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003047 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003048 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003049 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003050 << "SyncGroup should be set based on sync_label";
3051 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003052 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003053 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003054}
3055
solenberg3a941542015-11-16 07:34:50 -08003056// TODO(solenberg): Remove, once recv streams are configured through Call.
3057// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003058TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003059 // Test that setting the header extensions results in the expected state
3060 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003061 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003062 ssrcs.push_back(223);
3063 ssrcs.push_back(224);
3064
solenbergff976312016-03-30 23:28:51 -07003065 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003066 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003067 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003068 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003069 cricket::StreamParams::CreateLegacy(ssrc)));
3070 }
3071
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003072 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003073 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003074 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003075 EXPECT_NE(nullptr, s);
3076 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3077 }
3078
3079 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003080 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003081 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003082 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003083 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003084 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003085 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003086 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003087 EXPECT_NE(nullptr, s);
3088 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003089 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3090 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 for (const auto& s_ext : s_exts) {
3092 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003093 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003094 }
3095 }
3096 }
3097 }
3098
3099 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003100 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003101 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003102 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003103 EXPECT_NE(nullptr, s);
3104 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3105 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003106}
3107
3108TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3109 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003110 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003111 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 static const unsigned char kRtcp[] = {
3113 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3114 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3117 };
jbaucheec21bd2016-03-20 06:15:43 -07003118 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119
solenbergff976312016-03-30 23:28:51 -07003120 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003121 cricket::WebRtcVoiceMediaChannel* media_channel =
3122 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003123 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003124 EXPECT_TRUE(media_channel->AddRecvStream(
3125 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3126
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003127 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003129 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 EXPECT_EQ(0, s->received_packets());
3131 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3132 EXPECT_EQ(1, s->received_packets());
3133 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3134 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003135}
Minyue2013aec2015-05-13 14:14:42 +02003136
solenberg0a617e22015-10-20 15:49:38 -07003137// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003138// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003139TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003140 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003141 EXPECT_TRUE(AddRecvStream(kSsrcY));
3142 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003143 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003144 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3145 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3146 EXPECT_TRUE(AddRecvStream(kSsrcW));
3147 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003148}
3149
solenberg7602aab2016-11-14 11:30:07 -08003150TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3151 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003152 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003153 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003154 cricket::StreamParams::CreateLegacy(kSsrcY)));
3155 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3156 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3157 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003158 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003159 cricket::StreamParams::CreateLegacy(kSsrcW)));
3160 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3161 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003162}
stefan658910c2015-09-03 05:48:32 -07003163
deadbeef884f5852016-01-15 09:20:04 -08003164TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003165 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003166 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3167 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003168
3169 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003170 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3171 EXPECT_TRUE(AddRecvStream(kSsrcX));
3172 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003173
3174 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003175 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3176 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003177
3178 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003179 channel_->SetRawAudioSink(kSsrcX, nullptr);
3180 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003181}
3182
solenberg2100c0b2017-03-01 11:29:29 -08003183TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003184 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003185 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3186 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003187 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3188 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003189
3190 // Should be able to set a default sink even when no stream exists.
3191 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3192
solenberg2100c0b2017-03-01 11:29:29 -08003193 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3194 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003195 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003196 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003197
3198 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003199 channel_->SetRawAudioSink(kSsrc0, nullptr);
3200 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003201
3202 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003203 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3204 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003207 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003208 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003209 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3210
3211 // Spawn another unsignaled stream - it should be assigned the default sink
3212 // and the previous unsignaled stream should lose it.
3213 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3214 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3215 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3216 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003217 if (kMaxUnsignaledRecvStreams > 1) {
3218 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3219 }
solenberg2100c0b2017-03-01 11:29:29 -08003220 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3221
3222 // Reset the default sink - the second unsignaled stream should lose it.
3223 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003224 if (kMaxUnsignaledRecvStreams > 1) {
3225 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3226 }
solenberg2100c0b2017-03-01 11:29:29 -08003227 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3228
3229 // Try setting the default sink while two streams exists.
3230 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003231 if (kMaxUnsignaledRecvStreams > 1) {
3232 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3233 }
solenberg2100c0b2017-03-01 11:29:29 -08003234 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3235
3236 // Try setting the sink for the first unsignaled stream using its known SSRC.
3237 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003238 if (kMaxUnsignaledRecvStreams > 1) {
3239 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3240 }
solenberg2100c0b2017-03-01 11:29:29 -08003241 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003242 if (kMaxUnsignaledRecvStreams > 1) {
3243 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3244 }
deadbeef884f5852016-01-15 09:20:04 -08003245}
3246
skvlad7a43d252016-03-22 15:32:27 -07003247// Test that, just like the video channel, the voice channel communicates the
3248// network state to the call.
3249TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003250 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003251
3252 EXPECT_EQ(webrtc::kNetworkUp,
3253 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3254 EXPECT_EQ(webrtc::kNetworkUp,
3255 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3256
3257 channel_->OnReadyToSend(false);
3258 EXPECT_EQ(webrtc::kNetworkDown,
3259 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3260 EXPECT_EQ(webrtc::kNetworkUp,
3261 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3262
3263 channel_->OnReadyToSend(true);
3264 EXPECT_EQ(webrtc::kNetworkUp,
3265 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3266 EXPECT_EQ(webrtc::kNetworkUp,
3267 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3268}
3269
aleloi18e0b672016-10-04 02:45:47 -07003270// Test that playout is still started after changing parameters
3271TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3272 SetupRecvStream();
3273 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003274 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003275
3276 // Changing RTP header extensions will recreate the AudioReceiveStream.
3277 cricket::AudioRecvParameters parameters;
3278 parameters.extensions.push_back(
3279 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3280 channel_->SetRecvParameters(parameters);
3281
solenberg2100c0b2017-03-01 11:29:29 -08003282 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003283}
3284
stefan658910c2015-09-03 05:48:32 -07003285// Tests that the library initializes and shuts down properly.
3286TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003287 // If the VoiceEngine wants to gather available codecs early, that's fine but
3288 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003289 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3290 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003291 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003292 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003293 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003294 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003295 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003296 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003297 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003298 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3299 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003300 EXPECT_TRUE(channel != nullptr);
3301 delete channel;
solenbergff976312016-03-30 23:28:51 -07003302}
stefan658910c2015-09-03 05:48:32 -07003303
solenbergff976312016-03-30 23:28:51 -07003304// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003305TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3306 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3307 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3308 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003309 // Return 100ms just in case this function gets called. If we don't,
3310 // we could enter a tight loop since the mock would return 0.
3311 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003312 {
peaha9cc40b2017-06-29 08:32:09 -07003313 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3314 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003315 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003316 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003317 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003318 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003319 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003320 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003321 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003322 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3323 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3324 EXPECT_TRUE(channel != nullptr);
3325 delete channel;
3326 }
stefan658910c2015-09-03 05:48:32 -07003327}
3328
ossu20a4b3f2017-04-27 02:08:52 -07003329// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3330TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003331 // TODO(ossu): Why are the payload types of codecs with non-static payload
3332 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003333 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3334 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003335 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003336 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003337 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003338 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003339 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003340 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3341 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3342 (clockrate == 0 || codec.clockrate == clockrate);
3343 };
3344 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003345 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003346 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003347 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003348 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003349 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003350 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003351 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003352 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003353 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003354 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003355 EXPECT_EQ(126, codec.id);
3356 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3357 // Remove these checks once both send and receive side assigns payload types
3358 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003359 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003360 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003361 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003362 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003363 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003364 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003365 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003366 EXPECT_EQ(111, codec.id);
3367 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3368 EXPECT_EQ("10", codec.params.find("minptime")->second);
3369 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3370 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003371 }
3372 }
stefan658910c2015-09-03 05:48:32 -07003373}
3374
3375// Tests that VoE supports at least 32 channels
3376TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003377 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3378 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003379 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003380 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003381 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003382 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003383 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003384 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003385 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003386
3387 cricket::VoiceMediaChannel* channels[32];
3388 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003389 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003390 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3391 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003392 if (!channel)
3393 break;
stefan658910c2015-09-03 05:48:32 -07003394 channels[num_channels++] = channel;
3395 }
3396
tfarina5237aaf2015-11-10 23:44:30 -08003397 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003398 EXPECT_EQ(expected, num_channels);
3399
3400 while (num_channels > 0) {
3401 delete channels[--num_channels];
3402 }
stefan658910c2015-09-03 05:48:32 -07003403}
3404
3405// Test that we set our preferred codecs properly.
3406TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003407 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3408 // - Check that our builtin codecs are usable by Channel.
3409 // - The codecs provided by the engine is usable by Channel.
3410 // It does not check that the codecs in the RecvParameters are actually
3411 // what we sent in - though it's probably reasonable to expect so, if
3412 // SetRecvParameters returns true.
3413 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003414 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3415 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003416 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003417 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003418 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003419 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003420 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003421 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003422 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003423 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3424 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003425 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003426 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003427 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003428}
ossu9def8002017-02-09 05:14:32 -08003429
3430TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3431 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003432 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3433 {48000, 2, 16000, 10000, 20000}};
3434 spec1.info.allow_comfort_noise = false;
3435 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003436 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003437 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3438 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003439 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003440 specs.push_back(webrtc::AudioCodecSpec{
3441 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3442 {16000, 1, 13300}});
3443 specs.push_back(
3444 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3445 specs.push_back(
3446 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003447
ossueb1fde42017-05-02 06:46:30 -07003448 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3449 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3450 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003451 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003452 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003453 .WillOnce(Return(specs));
3454
peaha9cc40b2017-06-29 08:32:09 -07003455 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3456 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003457 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003458 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003459 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003460 auto codecs = engine.recv_codecs();
3461 EXPECT_EQ(11, codecs.size());
3462
3463 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3464 // check the actual values safely, to provide better test results.
3465 auto get_codec =
3466 [&codecs](size_t index) -> const cricket::AudioCodec& {
3467 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3468 if (codecs.size() > index)
3469 return codecs[index];
3470 return missing_codec;
3471 };
3472
3473 // Ensure the general codecs are generated first and in order.
3474 for (size_t i = 0; i != specs.size(); ++i) {
3475 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3476 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3477 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3478 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3479 }
3480
3481 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003482 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003483 auto find_codec =
3484 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3485 for (size_t i = 0; i != codecs.size(); ++i) {
3486 const cricket::AudioCodec& codec = codecs[i];
3487 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3488 codec.clockrate == format.clockrate_hz &&
3489 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003490 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003491 }
3492 }
3493 return -1;
3494 };
3495
3496 // Ensure all supplementary codecs are generated last. Their internal ordering
3497 // is not important.
3498 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3499 const int num_specs = static_cast<int>(specs.size());
3500 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3501 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3502 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3503 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3504 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3505 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3506 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3507}