blob: 5ccd7d6bb62fe67238632028c182c8083d2daefd [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;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700599 stats.total_samples_received = 5678901;
600 stats.concealed_samples = 234;
solenberg85a04962015-10-27 03:35:21 -0700601 stats.expand_rate = 5.67f;
602 stats.speech_expand_rate = 8.90f;
603 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200604 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700605 stats.accelerate_rate = 4.56f;
606 stats.preemptive_expand_rate = 7.89f;
607 stats.decoding_calls_to_silence_generator = 12;
608 stats.decoding_calls_to_neteq = 345;
609 stats.decoding_normal = 67890;
610 stats.decoding_plc = 1234;
611 stats.decoding_cng = 5678;
612 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700613 stats.decoding_muted_output = 3456;
614 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200615 return stats;
616 }
617 void SetAudioReceiveStreamStats() {
618 for (auto* s : call_.GetAudioReceiveStreams()) {
619 s->SetStats(GetAudioReceiveStreamStats());
620 }
621 }
622 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700623 const auto stats = GetAudioReceiveStreamStats();
624 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
625 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
626 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
627 EXPECT_EQ(info.packets_lost, stats.packets_lost);
628 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
629 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800630 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700631 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
632 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
633 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200634 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700635 stats.jitter_buffer_preferred_ms);
636 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
637 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700638 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
639 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
solenberg85a04962015-10-27 03:35:21 -0700640 EXPECT_EQ(info.expand_rate, stats.expand_rate);
641 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
642 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200643 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700644 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
645 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200646 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700647 stats.decoding_calls_to_silence_generator);
648 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
649 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
650 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
651 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
652 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700653 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700654 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200655 }
hbos1acfbd22016-11-17 23:43:29 -0800656 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
657 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
658 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
659 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
660 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
661 codec.ToCodecParameters());
662 }
663 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
664 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
665 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
666 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
667 codec.ToCodecParameters());
668 }
669 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200670
peah8271d042016-11-22 07:24:52 -0800671 bool IsHighPassFilterEnabled() {
672 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
673 }
674
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700676 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700677 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800678 webrtc::test::MockGainControl& apm_gc_;
679 webrtc::test::MockEchoCancellation& apm_ec_;
680 webrtc::test::MockNoiseSuppression& apm_ns_;
681 webrtc::test::MockVoiceDetection& apm_vd_;
682 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700683 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200684 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000685 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700686 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700687 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200688 cricket::AudioSendParameters send_parameters_;
689 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800690 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700691 webrtc::AudioProcessing::Config apm_config_;
692
stefanba4c0e42016-02-04 04:12:24 -0800693 private:
694 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695};
696
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000697// Tests that we can create and destroy a channel.
698TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700699 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000700}
701
solenberg31fec402016-05-06 02:13:12 -0700702// Test that we can add a send stream and that it has the correct defaults.
703TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
704 EXPECT_TRUE(SetupChannel());
705 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800706 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
707 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
708 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700709 EXPECT_EQ("", config.rtp.c_name);
710 EXPECT_EQ(0u, config.rtp.extensions.size());
711 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
712 config.send_transport);
713}
714
715// Test that we can add a receive stream and that it has the correct defaults.
716TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
717 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800718 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700719 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800720 GetRecvStreamConfig(kSsrcX);
721 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700722 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
723 EXPECT_FALSE(config.rtp.transport_cc);
724 EXPECT_EQ(0u, config.rtp.extensions.size());
725 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
726 config.rtcp_send_transport);
727 EXPECT_EQ("", config.sync_group);
728}
729
stefanba4c0e42016-02-04 04:12:24 -0800730TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700731 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800732 bool opus_found = false;
733 for (cricket::AudioCodec codec : codecs) {
734 if (codec.name == "opus") {
735 EXPECT_TRUE(HasTransportCc(codec));
736 opus_found = true;
737 }
738 }
739 EXPECT_TRUE(opus_found);
740}
741
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742// Test that we set our inbound codecs properly, including changing PT.
743TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700744 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200745 cricket::AudioRecvParameters parameters;
746 parameters.codecs.push_back(kIsacCodec);
747 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800748 parameters.codecs.push_back(kTelephoneEventCodec1);
749 parameters.codecs.push_back(kTelephoneEventCodec2);
750 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200751 parameters.codecs[2].id = 126;
752 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800753 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700754 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
755 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
756 {{0, {"PCMU", 8000, 1}},
757 {106, {"ISAC", 16000, 1}},
758 {126, {"telephone-event", 8000, 1}},
759 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760}
761
762// Test that we fail to set an unknown inbound codec.
763TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700764 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200765 cricket::AudioRecvParameters parameters;
766 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700767 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200768 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769}
770
771// Test that we fail if we have duplicate types in the inbound list.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kCn16000Codec);
777 parameters.codecs[1].id = kIsacCodec.id;
778 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779}
780
781// Test that we can decode OPUS without stereo parameters.
782TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700783 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200784 cricket::AudioRecvParameters parameters;
785 parameters.codecs.push_back(kIsacCodec);
786 parameters.codecs.push_back(kPcmuCodec);
787 parameters.codecs.push_back(kOpusCodec);
788 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800789 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700790 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
791 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
792 {{0, {"PCMU", 8000, 1}},
793 {103, {"ISAC", 16000, 1}},
794 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
797// Test that we can decode OPUS with stereo = 0.
798TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700799 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200800 cricket::AudioRecvParameters parameters;
801 parameters.codecs.push_back(kIsacCodec);
802 parameters.codecs.push_back(kPcmuCodec);
803 parameters.codecs.push_back(kOpusCodec);
804 parameters.codecs[2].params["stereo"] = "0";
805 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800806 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700807 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
808 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
809 {{0, {"PCMU", 8000, 1}},
810 {103, {"ISAC", 16000, 1}},
811 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that we can decode OPUS with stereo = 1.
815TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700816 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200817 cricket::AudioRecvParameters parameters;
818 parameters.codecs.push_back(kIsacCodec);
819 parameters.codecs.push_back(kPcmuCodec);
820 parameters.codecs.push_back(kOpusCodec);
821 parameters.codecs[2].params["stereo"] = "1";
822 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800823 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700824 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
825 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
826 {{0, {"PCMU", 8000, 1}},
827 {103, {"ISAC", 16000, 1}},
828 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829}
830
831// Test that changes to recv codecs are applied to all streams.
832TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700833 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200834 cricket::AudioRecvParameters parameters;
835 parameters.codecs.push_back(kIsacCodec);
836 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800837 parameters.codecs.push_back(kTelephoneEventCodec1);
838 parameters.codecs.push_back(kTelephoneEventCodec2);
839 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200840 parameters.codecs[2].id = 126;
841 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700842 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
843 EXPECT_TRUE(AddRecvStream(ssrc));
844 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
845 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
846 {{0, {"PCMU", 8000, 1}},
847 {106, {"ISAC", 16000, 1}},
848 {126, {"telephone-event", 8000, 1}},
849 {107, {"telephone-event", 32000, 1}}})));
850 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851}
852
853TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700854 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200855 cricket::AudioRecvParameters parameters;
856 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800857 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859
solenberg2100c0b2017-03-01 11:29:29 -0800860 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800861 ASSERT_EQ(1, dm.count(106));
862 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
865// Test that we can apply the same set of codecs again while playing.
866TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700867 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200868 cricket::AudioRecvParameters parameters;
869 parameters.codecs.push_back(kIsacCodec);
870 parameters.codecs.push_back(kCn16000Codec);
871 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700872 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200873 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874
deadbeefcb383672017-04-26 16:28:42 -0700875 // Remapping a payload type to a different codec should fail.
876 parameters.codecs[0] = kOpusCodec;
877 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800879 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882// Test that we can add a codec while playing.
883TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700884 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 cricket::AudioRecvParameters parameters;
886 parameters.codecs.push_back(kIsacCodec);
887 parameters.codecs.push_back(kCn16000Codec);
888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700889 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200891 parameters.codecs.push_back(kOpusCodec);
892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800893 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894}
895
deadbeefcb383672017-04-26 16:28:42 -0700896// Test that we accept adding the same codec with a different payload type.
897// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
898TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
899 EXPECT_TRUE(SetupRecvStream());
900 cricket::AudioRecvParameters parameters;
901 parameters.codecs.push_back(kIsacCodec);
902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
903
904 ++parameters.codecs[0].id;
905 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
906}
907
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700909 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000911 // Test that when autobw is enabled, bitrate is kept as the default
912 // value. autobw is enabled for the following tests because the target
913 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
915 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700916 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917
918 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700919 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
ossu20a4b3f2017-04-27 02:08:52 -0700921 // opus, default bitrate == 32000 in mono.
922 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000925TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700926 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700929 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
930 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700931 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700934 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
935 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
936 // Rates above the max (510000) should be capped.
937 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938}
939
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700941 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000942
943 // Test that we can only set a maximum bitrate for a fixed-rate codec
944 // if it's bigger than the fixed rate.
945
946 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700947 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
948 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
949 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
950 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
951 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
952 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
953 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954}
955
956TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700957 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200958 const int kDesiredBitrate = 128000;
959 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700960 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200961 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700962 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000963
964 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800965 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000966
solenberg2100c0b2017-03-01 11:29:29 -0800967 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000968}
969
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970// Test that bitrate cannot be set for CBR codecs.
971// Bitrate is ignored if it is higher than the fixed bitrate.
972// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000973TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700974 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975
976 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700977 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800978 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200979
980 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700981 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800982 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200983
984 send_parameters_.max_bandwidth_bps = 128;
985 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800986 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987}
988
skvlade0d46372016-04-07 22:59:22 -0700989// Test that the per-stream bitrate limit and the global
990// bitrate limit both apply.
991TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
992 EXPECT_TRUE(SetupSendStream());
993
ossu20a4b3f2017-04-27 02:08:52 -0700994 // opus, default bitrate == 32000.
995 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700996 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
997 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
998 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
999
1000 // CBR codecs allow both maximums to exceed the bitrate.
1001 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1002 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1003 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1004 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1005
1006 // CBR codecs don't allow per stream maximums to be too low.
1007 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1008 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1009}
1010
1011// Test that an attempt to set RtpParameters for a stream that does not exist
1012// fails.
1013TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1014 EXPECT_TRUE(SetupChannel());
1015 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001016 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001017 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1018
1019 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001020 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001021}
1022
1023TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001024 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001025 // This test verifies that setting RtpParameters succeeds only if
1026 // the structure contains exactly one encoding.
1027 // TODO(skvlad): Update this test when we start supporting setting parameters
1028 // for each encoding individually.
1029
1030 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001031 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001032 // Two or more encodings should result in failure.
1033 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001034 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001035 // Zero encodings should also fail.
1036 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001037 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001038}
1039
1040// Changing the SSRC through RtpParameters is not allowed.
1041TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1042 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001043 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001044 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001045 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001046}
1047
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001048// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001049// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001050TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1051 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001052 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001053 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001054 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001055 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001056 ASSERT_EQ(1u, parameters.encodings.size());
1057 ASSERT_TRUE(parameters.encodings[0].active);
1058 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001059 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1060 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001061
1062 // Now change it back to active and verify we resume sending.
1063 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001064 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1065 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001066}
1067
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001068// Test that SetRtpSendParameters configures the correct encoding channel for
1069// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001070TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1071 SetupForMultiSendStream();
1072 // Create send streams.
1073 for (uint32_t ssrc : kSsrcs4) {
1074 EXPECT_TRUE(
1075 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1076 }
1077 // Configure one stream to be limited by the stream config, another to be
1078 // limited by the global max, and the third one with no per-stream limit
1079 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001080 SetGlobalMaxBitrate(kOpusCodec, 32000);
1081 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1082 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001083 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1084
ossu20a4b3f2017-04-27 02:08:52 -07001085 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1086 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1087 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001088
1089 // Remove the global cap; the streams should switch to their respective
1090 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001091 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001092 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1093 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1094 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001095}
1096
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097// Test that GetRtpSendParameters returns the currently configured codecs.
1098TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001099 EXPECT_TRUE(SetupSendStream());
1100 cricket::AudioSendParameters parameters;
1101 parameters.codecs.push_back(kIsacCodec);
1102 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001103 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001104
solenberg2100c0b2017-03-01 11:29:29 -08001105 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001106 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001107 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1108 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001109}
1110
deadbeefcb443432016-12-12 11:12:36 -08001111// Test that GetRtpSendParameters returns an SSRC.
1112TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1113 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001114 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001115 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001116 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001117}
1118
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001119// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001120TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001121 EXPECT_TRUE(SetupSendStream());
1122 cricket::AudioSendParameters parameters;
1123 parameters.codecs.push_back(kIsacCodec);
1124 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001125 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001126
solenberg2100c0b2017-03-01 11:29:29 -08001127 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001128
1129 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001130 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001131
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001132 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001133 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1134 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001135}
1136
minyuececec102017-03-27 13:04:25 -07001137// Test that max_bitrate_bps in send stream config gets updated correctly when
1138// SetRtpSendParameters is called.
1139TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1140 webrtc::test::ScopedFieldTrials override_field_trials(
1141 "WebRTC-Audio-SendSideBwe/Enabled/");
1142 EXPECT_TRUE(SetupSendStream());
1143 cricket::AudioSendParameters send_parameters;
1144 send_parameters.codecs.push_back(kOpusCodec);
1145 SetSendParameters(send_parameters);
1146
1147 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1148 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1149 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1150
1151 constexpr int kMaxBitrateBps = 6000;
1152 rtp_parameters.encodings[0].max_bitrate_bps =
1153 rtc::Optional<int>(kMaxBitrateBps);
1154 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1155
1156 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1157 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1158}
1159
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160// Test that GetRtpReceiveParameters returns the currently configured codecs.
1161TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1162 EXPECT_TRUE(SetupRecvStream());
1163 cricket::AudioRecvParameters parameters;
1164 parameters.codecs.push_back(kIsacCodec);
1165 parameters.codecs.push_back(kPcmuCodec);
1166 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1167
1168 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001169 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001170 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1171 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1172 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1173}
1174
deadbeefcb443432016-12-12 11:12:36 -08001175// Test that GetRtpReceiveParameters returns an SSRC.
1176TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1177 EXPECT_TRUE(SetupRecvStream());
1178 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001179 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001180 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001181 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001182}
1183
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001184// Test that if we set/get parameters multiple times, we get the same results.
1185TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1186 EXPECT_TRUE(SetupRecvStream());
1187 cricket::AudioRecvParameters parameters;
1188 parameters.codecs.push_back(kIsacCodec);
1189 parameters.codecs.push_back(kPcmuCodec);
1190 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1191
1192 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001193 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001194
1195 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001196 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001197
1198 // ... And this shouldn't change the params returned by
1199 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001200 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1201 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001202}
1203
deadbeef3bc15102017-04-20 19:25:07 -07001204// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1205// aren't signaled. It should return an empty "RtpEncodingParameters" when
1206// configured to receive an unsignaled stream and no packets have been received
1207// yet, and start returning the SSRC once a packet has been received.
1208TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1209 ASSERT_TRUE(SetupChannel());
1210 // Call necessary methods to configure receiving a default stream as
1211 // soon as it arrives.
1212 cricket::AudioRecvParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
1215 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1216
1217 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1218 // stream. Should return nothing.
1219 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1220
1221 // Set a sink for an unsignaled stream.
1222 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1223 // Value of "0" means "unsignaled stream".
1224 channel_->SetRawAudioSink(0, std::move(fake_sink));
1225
1226 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1227 // in this method means "unsignaled stream".
1228 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1229 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1230 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1231
1232 // Receive PCMU packet (SSRC=1).
1233 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1234
1235 // The |ssrc| member should still be unset.
1236 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1237 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1238 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1239}
1240
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001241// Test that we apply codecs properly.
1242TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001243 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001244 cricket::AudioSendParameters parameters;
1245 parameters.codecs.push_back(kIsacCodec);
1246 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001247 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001248 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001249 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001250 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001251 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1252 EXPECT_EQ(96, send_codec_spec.payload_type);
1253 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1254 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1255 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1256 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001257 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001258}
1259
ossu20a4b3f2017-04-27 02:08:52 -07001260// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1261// AudioSendStream.
1262TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001263 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001264 cricket::AudioSendParameters parameters;
1265 parameters.codecs.push_back(kIsacCodec);
1266 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001267 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001268 parameters.codecs[0].id = 96;
1269 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001270 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001271 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001272 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001273 // Calling SetSendCodec again with same codec which is already set.
1274 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001275 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001276 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001277}
1278
ossu20a4b3f2017-04-27 02:08:52 -07001279// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1280// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001281
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001282// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kOpusCodec);
1287 parameters.codecs[0].bitrate = 0;
1288 parameters.codecs[0].clockrate = 50000;
1289 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290}
1291
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001292// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001294 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001295 cricket::AudioSendParameters parameters;
1296 parameters.codecs.push_back(kOpusCodec);
1297 parameters.codecs[0].bitrate = 0;
1298 parameters.codecs[0].channels = 0;
1299 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300}
1301
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001302// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001304 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001305 cricket::AudioSendParameters parameters;
1306 parameters.codecs.push_back(kOpusCodec);
1307 parameters.codecs[0].bitrate = 0;
1308 parameters.codecs[0].channels = 0;
1309 parameters.codecs[0].params["stereo"] = "1";
1310 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311}
1312
1313// Test that if channel is 1 for opus and there's no stereo, we fail.
1314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].channels = 1;
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
1323// Test that if channel is 1 for opus and stereo=0, we fail.
1324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001325 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 cricket::AudioSendParameters parameters;
1327 parameters.codecs.push_back(kOpusCodec);
1328 parameters.codecs[0].bitrate = 0;
1329 parameters.codecs[0].channels = 1;
1330 parameters.codecs[0].params["stereo"] = "0";
1331 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
1334// Test that if channel is 1 for opus and stereo=1, we fail.
1335TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001336 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001337 cricket::AudioSendParameters parameters;
1338 parameters.codecs.push_back(kOpusCodec);
1339 parameters.codecs[0].bitrate = 0;
1340 parameters.codecs[0].channels = 1;
1341 parameters.codecs[0].params["stereo"] = "1";
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
ossu20a4b3f2017-04-27 02:08:52 -07001345// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001351 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001352 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001353}
1354
ossu20a4b3f2017-04-27 02:08:52 -07001355// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001357 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001358 cricket::AudioSendParameters parameters;
1359 parameters.codecs.push_back(kOpusCodec);
1360 parameters.codecs[0].bitrate = 0;
1361 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001362 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001363 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001364}
1365
ossu20a4b3f2017-04-27 02:08:52 -07001366// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001368 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 cricket::AudioSendParameters parameters;
1370 parameters.codecs.push_back(kOpusCodec);
1371 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001372 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001374 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001375 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001376
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001378 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001379 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001380}
1381
ossu20a4b3f2017-04-27 02:08:52 -07001382// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001384 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001385 cricket::AudioSendParameters parameters;
1386 parameters.codecs.push_back(kOpusCodec);
1387 parameters.codecs[0].bitrate = 0;
1388 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001389 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001390 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391}
1392
ossu20a4b3f2017-04-27 02:08:52 -07001393// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001394TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001395 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001396 cricket::AudioSendParameters parameters;
1397 parameters.codecs.push_back(kOpusCodec);
1398 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001399 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001401 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001402 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001403
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001404 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001407}
1408
ossu20a4b3f2017-04-27 02:08:52 -07001409// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001415 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001416 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1417 EXPECT_EQ(111, spec.payload_type);
1418 EXPECT_EQ(96000, spec.target_bitrate_bps);
1419 EXPECT_EQ("opus", spec.format.name);
1420 EXPECT_EQ(2, spec.format.num_channels);
1421 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422}
1423
ossu20a4b3f2017-04-27 02:08:52 -07001424// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001426 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001427 cricket::AudioSendParameters parameters;
1428 parameters.codecs.push_back(kOpusCodec);
1429 parameters.codecs[0].bitrate = 30000;
1430 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433}
1434
ossu20a4b3f2017-04-27 02:08:52 -07001435// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001437 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 cricket::AudioSendParameters parameters;
1439 parameters.codecs.push_back(kOpusCodec);
1440 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001441 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001442 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443}
1444
ossu20a4b3f2017-04-27 02:08:52 -07001445// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 cricket::AudioSendParameters parameters;
1449 parameters.codecs.push_back(kOpusCodec);
1450 parameters.codecs[0].bitrate = 30000;
1451 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001452 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001453 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001454}
1455
stefan13f1a0a2016-11-30 07:22:58 -08001456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1457 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1458 200000);
1459}
1460
1461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1462 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1463}
1464
1465TEST_F(WebRtcVoiceEngineTestFake,
1466 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1467 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1468}
1469
1470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1471 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1472}
1473
1474TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001475 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001476 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1477 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001478 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001479 SetSendParameters(send_parameters_);
1480 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1481 << "Setting max bitrate should keep previous min bitrate.";
1482 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1483 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001484 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001485}
1486
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001487// Test that we can enable NACK with opus as caller.
1488TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001489 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001490 cricket::AudioSendParameters parameters;
1491 parameters.codecs.push_back(kOpusCodec);
1492 parameters.codecs[0].AddFeedbackParam(
1493 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1494 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001495 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001496 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001497 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498}
1499
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001500// Test that we can enable NACK with opus as callee.
1501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001502 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001503 cricket::AudioSendParameters parameters;
1504 parameters.codecs.push_back(kOpusCodec);
1505 parameters.codecs[0].AddFeedbackParam(
1506 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1507 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001508 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001509 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001510 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001511 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001512
1513 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001514 cricket::StreamParams::CreateLegacy(kSsrcX)));
1515 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001516}
1517
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001518// Test that we can enable NACK on receive streams.
1519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 cricket::AudioSendParameters parameters;
1523 parameters.codecs.push_back(kOpusCodec);
1524 parameters.codecs[0].AddFeedbackParam(
1525 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1526 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1528 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001529 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001530 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1531 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532}
1533
1534// Test that we can disable NACK.
1535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].AddFeedbackParam(
1540 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1541 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001542 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001543 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001544
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 parameters.codecs.clear();
1546 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001547 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001548 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001549}
1550
1551// Test that we can disable NACK on receive streams.
1552TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001553 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001555 cricket::AudioSendParameters parameters;
1556 parameters.codecs.push_back(kOpusCodec);
1557 parameters.codecs[0].AddFeedbackParam(
1558 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1559 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1562 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 parameters.codecs.clear();
1565 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001566 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001567 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1568 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569}
1570
1571// Test that NACK is enabled on a new receive stream.
1572TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001573 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001574 cricket::AudioSendParameters parameters;
1575 parameters.codecs.push_back(kIsacCodec);
1576 parameters.codecs.push_back(kCn16000Codec);
1577 parameters.codecs[0].AddFeedbackParam(
1578 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1579 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001580 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001582
solenberg2100c0b2017-03-01 11:29:29 -08001583 EXPECT_TRUE(AddRecvStream(kSsrcY));
1584 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1585 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1586 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587}
1588
stefanba4c0e42016-02-04 04:12:24 -08001589TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001590 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001591 cricket::AudioSendParameters send_parameters;
1592 send_parameters.codecs.push_back(kOpusCodec);
1593 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001594 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001595
1596 cricket::AudioRecvParameters recv_parameters;
1597 recv_parameters.codecs.push_back(kIsacCodec);
1598 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_TRUE(AddRecvStream(kSsrcX));
1600 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001601 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001602 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001603
ossudedfd282016-06-14 07:12:39 -07001604 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001606 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001607 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001608 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001609}
1610
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001611// Test that we can switch back and forth between Opus and ISAC with CN.
1612TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001613 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001614
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001615 cricket::AudioSendParameters opus_parameters;
1616 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001617 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001618 {
ossu20a4b3f2017-04-27 02:08:52 -07001619 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1620 EXPECT_EQ(111, spec.payload_type);
1621 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001622 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 cricket::AudioSendParameters isac_parameters;
1625 isac_parameters.codecs.push_back(kIsacCodec);
1626 isac_parameters.codecs.push_back(kCn16000Codec);
1627 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001628 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001629 {
ossu20a4b3f2017-04-27 02:08:52 -07001630 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1631 EXPECT_EQ(103, spec.payload_type);
1632 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001633 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001634
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001636 {
ossu20a4b3f2017-04-27 02:08:52 -07001637 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1638 EXPECT_EQ(111, spec.payload_type);
1639 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001640 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001641}
1642
1643// Test that we handle various ways of specifying bitrate.
1644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters parameters;
1647 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001649 {
ossu20a4b3f2017-04-27 02:08:52 -07001650 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1651 EXPECT_EQ(103, spec.payload_type);
1652 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1653 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001654 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001655
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001656 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001658 {
ossu20a4b3f2017-04-27 02:08:52 -07001659 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1660 EXPECT_EQ(103, spec.payload_type);
1661 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1662 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001663 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001666 {
ossu20a4b3f2017-04-27 02:08:52 -07001667 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1668 EXPECT_EQ(103, spec.payload_type);
1669 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1670 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001671 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001673 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001674 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001675 {
ossu20a4b3f2017-04-27 02:08:52 -07001676 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1677 EXPECT_EQ(0, spec.payload_type);
1678 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1679 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001680 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001682 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001684 {
ossu20a4b3f2017-04-27 02:08:52 -07001685 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1686 EXPECT_EQ(0, spec.payload_type);
1687 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1688 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001689 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001691 parameters.codecs[0] = kOpusCodec;
1692 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001693 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001694 {
ossu20a4b3f2017-04-27 02:08:52 -07001695 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1696 EXPECT_EQ(111, spec.payload_type);
1697 EXPECT_STREQ("opus", spec.format.name.c_str());
1698 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001699 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700}
1701
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001702// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001704 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 cricket::AudioSendParameters parameters;
1706 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001707}
1708
1709// Test that we can set send codecs even with telephone-event codec as the first
1710// one on the list.
1711TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001712 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001713 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001714 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001715 parameters.codecs.push_back(kIsacCodec);
1716 parameters.codecs.push_back(kPcmuCodec);
1717 parameters.codecs[0].id = 98; // DTMF
1718 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001720 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1721 EXPECT_EQ(96, spec.payload_type);
1722 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001723 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001724}
1725
solenberg31642aa2016-03-14 08:00:37 -07001726// Test that payload type range is limited for telephone-event codec.
1727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001729 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001730 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001731 parameters.codecs.push_back(kIsacCodec);
1732 parameters.codecs[0].id = 0; // DTMF
1733 parameters.codecs[1].id = 96;
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 = 128; // DTMF
1737 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1738 EXPECT_FALSE(channel_->CanInsertDtmf());
1739 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001740 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001741 EXPECT_TRUE(channel_->CanInsertDtmf());
1742 parameters.codecs[0].id = -1; // DTMF
1743 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1744 EXPECT_FALSE(channel_->CanInsertDtmf());
1745}
1746
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001747// Test that we can set send codecs even with CN codec as the first
1748// one on the list.
1749TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001750 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001751 cricket::AudioSendParameters parameters;
1752 parameters.codecs.push_back(kCn16000Codec);
1753 parameters.codecs.push_back(kIsacCodec);
1754 parameters.codecs.push_back(kPcmuCodec);
1755 parameters.codecs[0].id = 98; // wideband CN
1756 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001757 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001758 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1759 EXPECT_EQ(96, send_codec_spec.payload_type);
1760 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001761 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001762}
1763
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001764// Test that we set VAD and DTMF types correctly as caller.
1765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kIsacCodec);
1769 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 parameters.codecs.push_back(kCn16000Codec);
1772 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001773 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001774 parameters.codecs[0].id = 96;
1775 parameters.codecs[2].id = 97; // wideband CN
1776 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001778 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1779 EXPECT_EQ(96, send_codec_spec.payload_type);
1780 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1781 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001782 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001783 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784}
1785
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001786// Test that we set VAD and DTMF types correctly as callee.
1787TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001789 cricket::AudioSendParameters parameters;
1790 parameters.codecs.push_back(kIsacCodec);
1791 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001792 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001793 parameters.codecs.push_back(kCn16000Codec);
1794 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001795 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 parameters.codecs[0].id = 96;
1797 parameters.codecs[2].id = 97; // wideband CN
1798 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001799 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001800 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001801 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001802
ossu20a4b3f2017-04-27 02:08:52 -07001803 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1804 EXPECT_EQ(96, send_codec_spec.payload_type);
1805 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1806 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001807 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001808 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001809}
1810
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811// Test that we only apply VAD if we have a CN codec that matches the
1812// send codec clockrate.
1813TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001814 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001817 parameters.codecs.push_back(kIsacCodec);
1818 parameters.codecs.push_back(kCn16000Codec);
1819 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001821 {
ossu20a4b3f2017-04-27 02:08:52 -07001822 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1823 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1824 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001825 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001826 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001828 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001829 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001830 {
ossu20a4b3f2017-04-27 02:08:52 -07001831 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1832 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1833 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001834 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001837 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001838 {
ossu20a4b3f2017-04-27 02:08:52 -07001839 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1840 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1841 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001842 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001843 }
Brave Yao5225dd82015-03-26 07:39:19 +08001844 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001846 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001847 {
ossu20a4b3f2017-04-27 02:08:52 -07001848 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1849 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1850 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001851 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852}
1853
1854// Test that we perform case-insensitive matching of codec names.
1855TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001856 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001857 cricket::AudioSendParameters parameters;
1858 parameters.codecs.push_back(kIsacCodec);
1859 parameters.codecs.push_back(kPcmuCodec);
1860 parameters.codecs.push_back(kCn16000Codec);
1861 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001862 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001863 parameters.codecs[0].name = "iSaC";
1864 parameters.codecs[0].id = 96;
1865 parameters.codecs[2].id = 97; // wideband CN
1866 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001867 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001868 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1869 EXPECT_EQ(96, send_codec_spec.payload_type);
1870 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1871 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001872 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001873 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001874}
1875
stefanba4c0e42016-02-04 04:12:24 -08001876class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1877 public:
1878 WebRtcVoiceEngineWithSendSideBweTest()
1879 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1880};
1881
1882TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1883 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001884 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001885 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001886 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1887 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1888 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001889 extension.id);
1890 return;
1891 }
1892 }
1893 FAIL() << "Transport sequence number extension not in header-extension list.";
1894}
1895
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001896// Test support for audio level header extension.
1897TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001898 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001899}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001900TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001901 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001902}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001903
solenbergd4adce42016-11-17 06:26:52 -08001904// Test support for transport sequence number header extension.
1905TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1906 TestSetSendRtpHeaderExtensions(
1907 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001908}
solenbergd4adce42016-11-17 06:26:52 -08001909TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1910 TestSetRecvRtpHeaderExtensions(
1911 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001912}
1913
solenberg1ac56142015-10-13 03:58:19 -07001914// Test that we can create a channel and start sending on it.
1915TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001916 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001917 SetSendParameters(send_parameters_);
1918 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001919 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001920 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001921 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001922}
1923
1924// Test that a channel will send if and only if it has a source and is enabled
1925// for sending.
1926TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001927 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001928 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001929 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001930 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001931 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1932 SetAudioSend(kSsrcX, true, &fake_source_);
1933 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1934 SetAudioSend(kSsrcX, true, nullptr);
1935 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001936}
1937
solenberg94218532016-06-16 10:53:22 -07001938// Test that a channel is muted/unmuted.
1939TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1940 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001942 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1943 SetAudioSend(kSsrcX, true, nullptr);
1944 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1945 SetAudioSend(kSsrcX, false, nullptr);
1946 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001947}
1948
solenberg6d6e7c52016-04-13 09:07:30 -07001949// Test that SetSendParameters() does not alter a stream's send state.
1950TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1951 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001952 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001953
1954 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001955 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001956 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001957
1958 // Changing RTP header extensions will recreate the AudioSendStream.
1959 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001960 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001962 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001963
1964 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001965 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001966 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001967
1968 // Changing RTP header extensions will recreate the AudioSendStream.
1969 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001971 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001972}
1973
solenberg1ac56142015-10-13 03:58:19 -07001974// Test that we can create a channel and start playing out on it.
1975TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001976 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001977 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001978 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001979 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001980 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001981 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001982}
1983
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001984// Test that we can add and remove send streams.
1985TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1986 SetupForMultiSendStream();
1987
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001988 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001989 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001990
solenbergc96df772015-10-21 13:01:53 -07001991 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001992 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001993 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001994 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001996 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001997 }
tfarina5237aaf2015-11-10 23:44:30 -08001998 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001999
solenbergc96df772015-10-21 13:01:53 -07002000 // Delete the send streams.
2001 for (uint32_t ssrc : kSsrcs4) {
2002 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002003 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002004 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002005 }
solenbergc96df772015-10-21 13:01:53 -07002006 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002007}
2008
2009// Test SetSendCodecs correctly configure the codecs in all send streams.
2010TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2011 SetupForMultiSendStream();
2012
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002014 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002016 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002017 }
2018
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002020 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002021 parameters.codecs.push_back(kIsacCodec);
2022 parameters.codecs.push_back(kCn16000Codec);
2023 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002024 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002025
2026 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002027 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002028 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2029 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002030 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2031 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2032 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002033 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034 }
2035
minyue7a973442016-10-20 03:27:12 -07002036 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002037 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002038 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002039 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002040 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2041 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002042 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2043 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2044 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 }
2046}
2047
2048// Test we can SetSend on all send streams correctly.
2049TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2050 SetupForMultiSendStream();
2051
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002052 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002053 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002055 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002056 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002057 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002058 }
2059
2060 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002061 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002062 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002064 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002065 }
2066
2067 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002068 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002069 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002071 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002072 }
2073}
2074
2075// Test we can set the correct statistics on all send streams.
2076TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2077 SetupForMultiSendStream();
2078
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002080 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002081 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002082 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 }
solenberg85a04962015-10-27 03:35:21 -07002084
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002085 // Create a receive stream to check that none of the send streams end up in
2086 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002087 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002088
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002090 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002091 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002092 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002093
solenberg85a04962015-10-27 03:35:21 -07002094 // Check stats for the added streams.
2095 {
2096 cricket::VoiceMediaInfo info;
2097 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002098
solenberg85a04962015-10-27 03:35:21 -07002099 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002100 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002101 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002102 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002103 }
hbos1acfbd22016-11-17 23:43:29 -08002104 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002105
2106 // We have added one receive stream. We should see empty stats.
2107 EXPECT_EQ(info.receivers.size(), 1u);
2108 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 }
solenberg1ac56142015-10-13 03:58:19 -07002110
solenberg2100c0b2017-03-01 11:29:29 -08002111 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002112 {
2113 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002114 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002115 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002116 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002117 EXPECT_EQ(0u, info.receivers.size());
2118 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002119
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002120 // Deliver a new packet - a default receive stream should be created and we
2121 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002122 {
2123 cricket::VoiceMediaInfo info;
2124 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2125 SetAudioReceiveStreamStats();
2126 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002127 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002128 EXPECT_EQ(1u, info.receivers.size());
2129 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002130 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002131 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132}
2133
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134// Test that we can add and remove receive streams, and do proper send/playout.
2135// We can receive on multiple streams while sending one stream.
2136TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002137 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002138
solenberg1ac56142015-10-13 03:58:19 -07002139 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002140 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002141 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002142
solenberg1ac56142015-10-13 03:58:19 -07002143 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002145 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002146 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002147
solenberg1ac56142015-10-13 03:58:19 -07002148 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002149 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002150
2151 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002152 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2153 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2154 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002155
2156 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002157 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002158 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002159
2160 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002161 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002162 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2163 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002164
aleloi84ef6152016-08-04 05:28:21 -07002165 // Restart playout and make sure recv streams are played out.
2166 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002167 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2168 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169
aleloi84ef6152016-08-04 05:28:21 -07002170 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002171 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2172 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002173}
2174
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002175// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002176// and start sending on it.
2177TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002178 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002179 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2180 EXPECT_CALL(apm_gc_,
2181 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002182 SetSendParameters(send_parameters_);
2183 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002184 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002185 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002186 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002187}
2188
wu@webrtc.org97077a32013-10-25 21:18:33 +00002189TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002190 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002191 EXPECT_CALL(adm_,
2192 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002193 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2194 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002195 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2196 send_parameters_.options.tx_agc_digital_compression_gain =
2197 rtc::Optional<uint16_t>(9);
2198 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2199 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002200 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2201 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2202 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002203 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002204
2205 // Check interaction with adjust_agc_delta. Both should be respected, for
2206 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002207 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002208 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002209 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002210}
2211
wu@webrtc.org97077a32013-10-25 21:18:33 +00002212TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002213 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002214 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2215 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002216 send_parameters_.options.recording_sample_rate =
2217 rtc::Optional<uint32_t>(48000);
2218 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002219 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002220}
2221
minyue6b825df2016-10-31 04:08:32 -07002222TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2223 EXPECT_TRUE(SetupSendStream());
2224 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2225 send_parameters_.options.audio_network_adaptor_config =
2226 rtc::Optional<std::string>("1234");
2227 SetSendParameters(send_parameters_);
2228 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002229 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002230}
2231
2232TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2233 EXPECT_TRUE(SetupSendStream());
2234 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2235 send_parameters_.options.audio_network_adaptor_config =
2236 rtc::Optional<std::string>("1234");
2237 SetSendParameters(send_parameters_);
2238 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002239 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002240 cricket::AudioOptions options;
2241 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002242 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002243 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002244}
2245
2246TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2247 EXPECT_TRUE(SetupSendStream());
2248 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2249 send_parameters_.options.audio_network_adaptor_config =
2250 rtc::Optional<std::string>("1234");
2251 SetSendParameters(send_parameters_);
2252 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002253 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002254 const int initial_num = call_.GetNumCreatedSendStreams();
2255 cricket::AudioOptions options;
2256 options.audio_network_adaptor = rtc::Optional<bool>();
2257 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2258 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002259 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002260 // AudioSendStream not expected to be recreated.
2261 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2262 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002263 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002264}
2265
michaelt6672b262017-01-11 10:17:59 -08002266class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2267 : public WebRtcVoiceEngineTestFake {
2268 public:
2269 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2270 : WebRtcVoiceEngineTestFake(
2271 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2272 "Enabled/") {}
2273};
2274
2275TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2276 EXPECT_TRUE(SetupSendStream());
2277 cricket::AudioSendParameters parameters;
2278 parameters.codecs.push_back(kOpusCodec);
2279 SetSendParameters(parameters);
2280 const int initial_num = call_.GetNumCreatedSendStreams();
2281 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2282
2283 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2284 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002285 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2286 constexpr int kMinOverheadBps =
2287 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002288
2289 constexpr int kOpusMinBitrateBps = 6000;
2290 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002291 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002292 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002293 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002294 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002295
2296 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2297 parameters.options.audio_network_adaptor_config =
2298 rtc::Optional<std::string>("1234");
2299 SetSendParameters(parameters);
2300
ossu11bfc532017-02-16 05:37:06 -08002301 constexpr int kMinOverheadWithAnaBps =
2302 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002303
2304 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002305 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002306
minyuececec102017-03-27 13:04:25 -07002307 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002308 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002309}
2310
minyuececec102017-03-27 13:04:25 -07002311// This test is similar to
2312// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2313// additional field trial.
2314TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2315 SetRtpSendParameterUpdatesMaxBitrate) {
2316 EXPECT_TRUE(SetupSendStream());
2317 cricket::AudioSendParameters send_parameters;
2318 send_parameters.codecs.push_back(kOpusCodec);
2319 SetSendParameters(send_parameters);
2320
2321 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2322 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2323 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2324
2325 constexpr int kMaxBitrateBps = 6000;
2326 rtp_parameters.encodings[0].max_bitrate_bps =
2327 rtc::Optional<int>(kMaxBitrateBps);
2328 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2329
2330 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2331#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2332 constexpr int kMinOverhead = 3333;
2333#else
2334 constexpr int kMinOverhead = 6666;
2335#endif
2336 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2337}
2338
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002339// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002340// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002341TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002342 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002343 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002344}
2345
2346TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2347 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002348 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002349 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002350 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002351 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002352 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002353 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002354 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002355
solenberg85a04962015-10-27 03:35:21 -07002356 // Check stats for the added streams.
2357 {
2358 cricket::VoiceMediaInfo info;
2359 EXPECT_EQ(true, channel_->GetStats(&info));
2360
2361 // We have added one send stream. We should see the stats we've set.
2362 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002363 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002364 // We have added one receive stream. We should see empty stats.
2365 EXPECT_EQ(info.receivers.size(), 1u);
2366 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2367 }
solenberg1ac56142015-10-13 03:58:19 -07002368
solenberg566ef242015-11-06 15:34:49 -08002369 // Start sending - this affects some reported stats.
2370 {
2371 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002372 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002373 EXPECT_EQ(true, channel_->GetStats(&info));
2374 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002375 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002376 }
2377
solenberg2100c0b2017-03-01 11:29:29 -08002378 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002379 {
2380 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002381 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002382 EXPECT_EQ(true, channel_->GetStats(&info));
2383 EXPECT_EQ(1u, info.senders.size());
2384 EXPECT_EQ(0u, info.receivers.size());
2385 }
solenberg1ac56142015-10-13 03:58:19 -07002386
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002387 // Deliver a new packet - a default receive stream should be created and we
2388 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002389 {
2390 cricket::VoiceMediaInfo info;
2391 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2392 SetAudioReceiveStreamStats();
2393 EXPECT_EQ(true, channel_->GetStats(&info));
2394 EXPECT_EQ(1u, info.senders.size());
2395 EXPECT_EQ(1u, info.receivers.size());
2396 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002397 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002398 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002399}
2400
2401// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002402// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002403TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002404 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002405 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2406 EXPECT_TRUE(AddRecvStream(kSsrcY));
2407 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002408}
2409
2410// Test that the local SSRC is the same on sending and receiving channels if the
2411// receive channel is created before the send channel.
2412TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002413 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002414 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002416 cricket::StreamParams::CreateLegacy(kSsrcX)));
2417 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2418 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419}
2420
2421// Test that we can properly receive packets.
2422TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002424 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002425 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002426
2427 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2428 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429}
2430
2431// Test that we can properly receive packets on multiple streams.
2432TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002433 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002434 const uint32_t ssrc1 = 1;
2435 const uint32_t ssrc2 = 2;
2436 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002437 EXPECT_TRUE(AddRecvStream(ssrc1));
2438 EXPECT_TRUE(AddRecvStream(ssrc2));
2439 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002441 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002442 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002444 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 }
mflodman3d7db262016-04-29 00:57:13 -07002446
2447 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2448 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2449 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2450
2451 EXPECT_EQ(s1.received_packets(), 0);
2452 EXPECT_EQ(s2.received_packets(), 0);
2453 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002454
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002456 EXPECT_EQ(s1.received_packets(), 0);
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[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002461 EXPECT_EQ(s1.received_packets(), 1);
2462 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2463 EXPECT_EQ(s2.received_packets(), 0);
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[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002467 EXPECT_EQ(s1.received_packets(), 1);
2468 EXPECT_EQ(s2.received_packets(), 1);
2469 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2470 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002471
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002473 EXPECT_EQ(s1.received_packets(), 1);
2474 EXPECT_EQ(s2.received_packets(), 1);
2475 EXPECT_EQ(s3.received_packets(), 1);
2476 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002477
mflodman3d7db262016-04-29 00:57:13 -07002478 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2479 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2480 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481}
2482
solenberg2100c0b2017-03-01 11:29:29 -08002483// Test that receiving on an unsignaled stream works (a stream is created).
2484TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002485 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2487
solenberg7e63ef02015-11-20 00:19:43 -08002488 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002489
2490 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002491 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2492 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002493}
2494
solenberg2100c0b2017-03-01 11:29:29 -08002495// Test that receiving N unsignaled stream works (streams will be created), and
2496// that packets are forwarded to them all.
2497TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002498 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002499 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002500 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2501
solenberg2100c0b2017-03-01 11:29:29 -08002502 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002503 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002504 rtc::SetBE32(&packet[8], ssrc);
2505 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002506
solenberg2100c0b2017-03-01 11:29:29 -08002507 // Verify we have one new stream for each loop iteration.
2508 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002509 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2510 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002511 }
mflodman3d7db262016-04-29 00:57:13 -07002512
solenberg2100c0b2017-03-01 11:29:29 -08002513 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002514 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002515 rtc::SetBE32(&packet[8], ssrc);
2516 DeliverPacket(packet, sizeof(packet));
2517
solenbergebb349d2017-03-13 05:46:15 -07002518 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002519 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2520 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2521 }
2522
2523 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2524 constexpr uint32_t kAnotherSsrc = 667;
2525 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002526 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002527
2528 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002529 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002530 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002531 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002532 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2533 EXPECT_EQ(2, streams[i]->received_packets());
2534 }
2535 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2536 EXPECT_EQ(1, streams[i]->received_packets());
2537 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002538 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002539}
2540
solenberg2100c0b2017-03-01 11:29:29 -08002541// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002542// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002543TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002544 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002545 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002546 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2547
2548 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002549 const uint32_t signaled_ssrc = 1;
2550 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002551 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002552 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002553 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2554 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002555 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002556
2557 // Note that the first unknown SSRC cannot be 0, because we only support
2558 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002559 const uint32_t unsignaled_ssrc = 7011;
2560 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002561 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002562 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2563 packet, sizeof(packet)));
2564 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2565
2566 DeliverPacket(packet, sizeof(packet));
2567 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2568
2569 rtc::SetBE32(&packet[8], signaled_ssrc);
2570 DeliverPacket(packet, sizeof(packet));
2571 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2572 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002573}
2574
solenberg4904fb62017-02-17 12:01:14 -08002575// Two tests to verify that adding a receive stream with the same SSRC as a
2576// previously added unsignaled stream will only recreate underlying stream
2577// objects if the stream parameters have changed.
2578TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2579 EXPECT_TRUE(SetupChannel());
2580
2581 // Spawn unsignaled stream with SSRC=1.
2582 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2583 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2584 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2585 sizeof(kPcmuFrame)));
2586
2587 // Verify that the underlying stream object in Call is not recreated when a
2588 // stream with SSRC=1 is added.
2589 const auto& streams = call_.GetAudioReceiveStreams();
2590 EXPECT_EQ(1, streams.size());
2591 int audio_receive_stream_id = streams.front()->id();
2592 EXPECT_TRUE(AddRecvStream(1));
2593 EXPECT_EQ(1, streams.size());
2594 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2595}
2596
2597TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2598 EXPECT_TRUE(SetupChannel());
2599
2600 // Spawn unsignaled stream with SSRC=1.
2601 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2602 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2603 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2604 sizeof(kPcmuFrame)));
2605
2606 // Verify that the underlying stream object in Call *is* recreated when a
2607 // stream with SSRC=1 is added, and which has changed stream parameters.
2608 const auto& streams = call_.GetAudioReceiveStreams();
2609 EXPECT_EQ(1, streams.size());
2610 int audio_receive_stream_id = streams.front()->id();
2611 cricket::StreamParams stream_params;
2612 stream_params.ssrcs.push_back(1);
2613 stream_params.sync_label = "sync_label";
2614 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2615 EXPECT_EQ(1, streams.size());
2616 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2617}
2618
solenberg0a617e22015-10-20 15:49:38 -07002619// Test that we properly handle failures to add a receive stream.
2620TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002621 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002622 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002623 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002624}
2625
solenberg0a617e22015-10-20 15:49:38 -07002626// Test that we properly handle failures to add a send stream.
2627TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002628 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002629 voe_.set_fail_create_channel(true);
2630 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2631}
2632
solenberg1ac56142015-10-13 03:58:19 -07002633// Test that AddRecvStream creates new stream.
2634TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002635 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002636 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002637 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002638 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002639}
2640
2641// Test that after adding a recv stream, we do not decode more codecs than
2642// those previously passed into SetRecvCodecs.
2643TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002644 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002645 cricket::AudioRecvParameters parameters;
2646 parameters.codecs.push_back(kIsacCodec);
2647 parameters.codecs.push_back(kPcmuCodec);
2648 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002649 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002650 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2651 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2652 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653}
2654
2655// Test that we properly clean up any streams that were added, even if
2656// not explicitly removed.
2657TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002658 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002659 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002660 EXPECT_TRUE(AddRecvStream(1));
2661 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2663 delete channel_;
2664 channel_ = NULL;
2665 EXPECT_EQ(0, voe_.GetNumChannels());
2666}
2667
wu@webrtc.org78187522013-10-07 23:32:02 +00002668TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002669 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002670 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002671}
2672
2673TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002675 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002676 // Manually delete channel to simulate a failure.
2677 int channel = voe_.GetLastChannel();
2678 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2679 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002680 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002681 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002682 EXPECT_NE(channel, new_channel);
2683 // The last created channel is deleted too.
2684 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002685}
2686
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002687// Test the InsertDtmf on default send stream as caller.
2688TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002689 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690}
2691
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002692// Test the InsertDtmf on default send stream as callee
2693TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002694 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002695}
2696
2697// Test the InsertDtmf on specified send stream as caller.
2698TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002699 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002700}
2701
2702// Test the InsertDtmf on specified send stream as callee.
2703TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002704 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705}
2706
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002707TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002708 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002709 EXPECT_CALL(adm_,
2710 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2711 EXPECT_CALL(adm_,
2712 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2713 EXPECT_CALL(adm_,
2714 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002715
solenberg246b8172015-12-08 09:50:23 -08002716 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2717 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718
solenberg246b8172015-12-08 09:50:23 -08002719 // Nothing set in AudioOptions, so everything should be as default.
2720 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002721 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002722 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002723 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2724 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725
2726 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002727 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2728 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002729 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002730 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002731
2732 // Turn echo cancellation back on, with settings, and make sure
2733 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002734 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2735 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002736 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002737 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002739 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2740 // control.
solenberg76377c52017-02-21 00:54:31 -08002741 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002743 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002744 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002745
2746 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002747 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2748 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002749 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2750 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2751 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002753
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002754 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002757 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002759
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002760 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002761 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2763 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002765 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002766 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767
2768 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2771 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002773 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2774 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002775 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776
2777 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002778 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2781 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2783 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2784 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002785 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2786 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2787 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2788 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002789 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002790 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791
solenberg1ac56142015-10-13 03:58:19 -07002792 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002793 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2794 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2795 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2797 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2799 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002800 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002803TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002804 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002805 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002806 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002807 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002808 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002809 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002810 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002811 EXPECT_CALL(adm_,
2812 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2813 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2814 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002815 webrtc::AudioProcessing::Config apm_config;
2816 EXPECT_CALL(*apm_, GetConfig())
2817 .Times(10)
2818 .WillRepeatedly(ReturnPointee(&apm_config));
2819 EXPECT_CALL(*apm_, ApplyConfig(_))
2820 .Times(10)
2821 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002822 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002823
kwiberg686a8ef2016-02-26 03:00:35 -08002824 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002825 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002826 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002827 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002828 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002829 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830
2831 // Have to add a stream to make SetSend work.
2832 cricket::StreamParams stream1;
2833 stream1.ssrcs.push_back(1);
2834 channel1->AddSendStream(stream1);
2835 cricket::StreamParams stream2;
2836 stream2.ssrcs.push_back(2);
2837 channel2->AddSendStream(stream2);
2838
2839 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002840 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002841 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2842 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2843 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002844 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2845 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2846 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2847 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2848 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002849 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002850 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002851 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002852 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002855 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002856 parameters_options_no_ns.options.noise_suppression =
2857 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2859 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002863 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002864 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002865 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2866 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2867 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002868 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869
2870 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002872 parameters_options_no_agc.options.auto_gain_control =
2873 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2878 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002879 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002880 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2881 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2882 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002883 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884
solenberg76377c52017-02-21 00:54:31 -08002885 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002890 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
solenberg76377c52017-02-21 00:54:31 -08002892 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002897 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2903 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002904 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002906 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002907 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2908 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002909 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002910 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002911 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002912 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002913 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2916 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002918 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002919 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2920 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2921 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002922 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002923}
2924
wu@webrtc.orgde305012013-10-31 15:40:38 +00002925// This test verifies DSCP settings are properly applied on voice media channel.
2926TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002927 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002928 cricket::FakeNetworkInterface network_interface;
2929 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002930 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002931
peahb1c9d1d2017-07-25 15:45:24 -07002932 webrtc::AudioProcessing::Config apm_config;
2933 EXPECT_CALL(*apm_, GetConfig())
2934 .Times(3)
2935 .WillRepeatedly(ReturnPointee(&apm_config));
2936 EXPECT_CALL(*apm_, ApplyConfig(_))
2937 .Times(3)
2938 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002939 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002940
solenbergbc37fc82016-04-04 09:54:44 -07002941 channel.reset(
2942 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002943 channel->SetInterface(&network_interface);
2944 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2945 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2946
2947 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002948 channel.reset(
2949 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002950 channel->SetInterface(&network_interface);
2951 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2952
2953 // Verify that setting the option to false resets the
2954 // DiffServCodePoint.
2955 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002956 channel.reset(
2957 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002958 channel->SetInterface(&network_interface);
2959 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2960 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2961
2962 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002963}
2964
solenberg1ac56142015-10-13 03:58:19 -07002965TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002966 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967 cricket::WebRtcVoiceMediaChannel* media_channel =
2968 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002969 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002970 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002971 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002972 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2973 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2974 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002975 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002976 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977}
2978
solenberg1ac56142015-10-13 03:58:19 -07002979TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002980 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002982 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2983 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2984 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002985 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002986 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002987 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2988 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002989 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002990 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002991 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002992 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993}
2994
solenberg4bac9c52015-10-09 02:32:53 -07002995TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002996 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002997 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002999 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003001 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3002 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3003 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003004}
3005
solenberg2100c0b2017-03-01 11:29:29 -08003006TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003007 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003008
3009 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003010 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003011 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3012
3013 // Should remember the volume "2" which will be set on new unsignaled streams,
3014 // and also set the gain to 2 on existing unsignaled streams.
3015 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3016 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3017
3018 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3019 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3020 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3021 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3022 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3023 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3024
3025 // Setting gain with SSRC=0 should affect all unsignaled streams.
3026 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003027 if (kMaxUnsignaledRecvStreams > 1) {
3028 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3029 }
solenberg2100c0b2017-03-01 11:29:29 -08003030 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3031
3032 // Setting gain on an individual stream affects only that.
3033 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003034 if (kMaxUnsignaledRecvStreams > 1) {
3035 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3036 }
solenberg2100c0b2017-03-01 11:29:29 -08003037 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003038}
3039
pbos8fc7fa72015-07-15 08:02:58 -07003040TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003041 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003042 const std::string kSyncLabel = "AvSyncLabel";
3043
solenbergff976312016-03-30 23:28:51 -07003044 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003045 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3046 sp.sync_label = kSyncLabel;
3047 // Creating two channels to make sure that sync label is set properly for both
3048 // the default voice channel and following ones.
3049 EXPECT_TRUE(channel_->AddRecvStream(sp));
3050 sp.ssrcs[0] += 1;
3051 EXPECT_TRUE(channel_->AddRecvStream(sp));
3052
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003053 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003054 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003055 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003056 << "SyncGroup should be set based on sync_label";
3057 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003058 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003059 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003060}
3061
solenberg3a941542015-11-16 07:34:50 -08003062// TODO(solenberg): Remove, once recv streams are configured through Call.
3063// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003064TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003065 // Test that setting the header extensions results in the expected state
3066 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003067 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003068 ssrcs.push_back(223);
3069 ssrcs.push_back(224);
3070
solenbergff976312016-03-30 23:28:51 -07003071 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003072 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003073 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003074 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003075 cricket::StreamParams::CreateLegacy(ssrc)));
3076 }
3077
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003078 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003079 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003080 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003081 EXPECT_NE(nullptr, s);
3082 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3083 }
3084
3085 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003086 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003087 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003088 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003089 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003090 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003091 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003092 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003093 EXPECT_NE(nullptr, s);
3094 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003095 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3096 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097 for (const auto& s_ext : s_exts) {
3098 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003099 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 }
3101 }
3102 }
3103 }
3104
3105 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003106 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003107 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003108 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109 EXPECT_NE(nullptr, s);
3110 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3111 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112}
3113
3114TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3115 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003116 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003117 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003118 static const unsigned char kRtcp[] = {
3119 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3120 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3123 };
jbaucheec21bd2016-03-20 06:15:43 -07003124 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125
solenbergff976312016-03-30 23:28:51 -07003126 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003127 cricket::WebRtcVoiceMediaChannel* media_channel =
3128 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003129 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130 EXPECT_TRUE(media_channel->AddRecvStream(
3131 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3132
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003133 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003135 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003136 EXPECT_EQ(0, s->received_packets());
3137 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3138 EXPECT_EQ(1, s->received_packets());
3139 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3140 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003141}
Minyue2013aec2015-05-13 14:14:42 +02003142
solenberg0a617e22015-10-20 15:49:38 -07003143// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003144// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003145TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003146 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003147 EXPECT_TRUE(AddRecvStream(kSsrcY));
3148 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003149 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003150 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3151 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3152 EXPECT_TRUE(AddRecvStream(kSsrcW));
3153 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003154}
3155
solenberg7602aab2016-11-14 11:30:07 -08003156TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3157 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003158 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003159 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003160 cricket::StreamParams::CreateLegacy(kSsrcY)));
3161 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3162 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3163 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003164 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003165 cricket::StreamParams::CreateLegacy(kSsrcW)));
3166 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3167 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003168}
stefan658910c2015-09-03 05:48:32 -07003169
deadbeef884f5852016-01-15 09:20:04 -08003170TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003171 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003172 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3173 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003174
3175 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003176 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3177 EXPECT_TRUE(AddRecvStream(kSsrcX));
3178 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003179
3180 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003181 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3182 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003183
3184 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003185 channel_->SetRawAudioSink(kSsrcX, nullptr);
3186 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003187}
3188
solenberg2100c0b2017-03-01 11:29:29 -08003189TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003191 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3192 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003193 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3194 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003195
3196 // Should be able to set a default sink even when no stream exists.
3197 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3198
solenberg2100c0b2017-03-01 11:29:29 -08003199 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3200 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003201 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003202 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003203
3204 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003205 channel_->SetRawAudioSink(kSsrc0, nullptr);
3206 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003207
3208 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003209 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3210 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003211
3212 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003213 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003214 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003215 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3216
3217 // Spawn another unsignaled stream - it should be assigned the default sink
3218 // and the previous unsignaled stream should lose it.
3219 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3220 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3221 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3222 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003223 if (kMaxUnsignaledRecvStreams > 1) {
3224 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3225 }
solenberg2100c0b2017-03-01 11:29:29 -08003226 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3227
3228 // Reset the default sink - the second unsignaled stream should lose it.
3229 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003230 if (kMaxUnsignaledRecvStreams > 1) {
3231 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3232 }
solenberg2100c0b2017-03-01 11:29:29 -08003233 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3234
3235 // Try setting the default sink while two streams exists.
3236 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003237 if (kMaxUnsignaledRecvStreams > 1) {
3238 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3239 }
solenberg2100c0b2017-03-01 11:29:29 -08003240 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3241
3242 // Try setting the sink for the first unsignaled stream using its known SSRC.
3243 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003244 if (kMaxUnsignaledRecvStreams > 1) {
3245 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3246 }
solenberg2100c0b2017-03-01 11:29:29 -08003247 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003248 if (kMaxUnsignaledRecvStreams > 1) {
3249 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3250 }
deadbeef884f5852016-01-15 09:20:04 -08003251}
3252
skvlad7a43d252016-03-22 15:32:27 -07003253// Test that, just like the video channel, the voice channel communicates the
3254// network state to the call.
3255TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003256 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003257
3258 EXPECT_EQ(webrtc::kNetworkUp,
3259 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3260 EXPECT_EQ(webrtc::kNetworkUp,
3261 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3262
3263 channel_->OnReadyToSend(false);
3264 EXPECT_EQ(webrtc::kNetworkDown,
3265 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3266 EXPECT_EQ(webrtc::kNetworkUp,
3267 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3268
3269 channel_->OnReadyToSend(true);
3270 EXPECT_EQ(webrtc::kNetworkUp,
3271 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3272 EXPECT_EQ(webrtc::kNetworkUp,
3273 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3274}
3275
aleloi18e0b672016-10-04 02:45:47 -07003276// Test that playout is still started after changing parameters
3277TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3278 SetupRecvStream();
3279 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003280 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003281
3282 // Changing RTP header extensions will recreate the AudioReceiveStream.
3283 cricket::AudioRecvParameters parameters;
3284 parameters.extensions.push_back(
3285 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3286 channel_->SetRecvParameters(parameters);
3287
solenberg2100c0b2017-03-01 11:29:29 -08003288 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003289}
3290
stefan658910c2015-09-03 05:48:32 -07003291// Tests that the library initializes and shuts down properly.
3292TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003293 // If the VoiceEngine wants to gather available codecs early, that's fine but
3294 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003295 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3296 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003297 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003298 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003299 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003300 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003301 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003302 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003303 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003304 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3305 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003306 EXPECT_TRUE(channel != nullptr);
3307 delete channel;
solenbergff976312016-03-30 23:28:51 -07003308}
stefan658910c2015-09-03 05:48:32 -07003309
solenbergff976312016-03-30 23:28:51 -07003310// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003311TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3312 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3313 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3314 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003315 // Return 100ms just in case this function gets called. If we don't,
3316 // we could enter a tight loop since the mock would return 0.
3317 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003318 {
peaha9cc40b2017-06-29 08:32:09 -07003319 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3320 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003321 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003322 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003323 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003324 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003325 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003326 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003327 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003328 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3329 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3330 EXPECT_TRUE(channel != nullptr);
3331 delete channel;
3332 }
stefan658910c2015-09-03 05:48:32 -07003333}
3334
ossu20a4b3f2017-04-27 02:08:52 -07003335// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3336TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003337 // TODO(ossu): Why are the payload types of codecs with non-static payload
3338 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003339 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3340 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003341 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003342 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003343 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003344 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003345 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003346 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3347 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3348 (clockrate == 0 || codec.clockrate == clockrate);
3349 };
3350 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003351 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003352 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003353 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003354 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003355 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003356 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003358 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003359 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003360 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003361 EXPECT_EQ(126, codec.id);
3362 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3363 // Remove these checks once both send and receive side assigns payload types
3364 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003365 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003366 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003367 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003368 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003369 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003370 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(111, codec.id);
3373 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3374 EXPECT_EQ("10", codec.params.find("minptime")->second);
3375 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3376 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003377 }
3378 }
stefan658910c2015-09-03 05:48:32 -07003379}
3380
3381// Tests that VoE supports at least 32 channels
3382TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003383 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3384 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003385 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003386 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003387 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003388 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003389 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003390 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003391 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003392
3393 cricket::VoiceMediaChannel* channels[32];
3394 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003395 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003396 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3397 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003398 if (!channel)
3399 break;
stefan658910c2015-09-03 05:48:32 -07003400 channels[num_channels++] = channel;
3401 }
3402
tfarina5237aaf2015-11-10 23:44:30 -08003403 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003404 EXPECT_EQ(expected, num_channels);
3405
3406 while (num_channels > 0) {
3407 delete channels[--num_channels];
3408 }
stefan658910c2015-09-03 05:48:32 -07003409}
3410
3411// Test that we set our preferred codecs properly.
3412TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003413 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3414 // - Check that our builtin codecs are usable by Channel.
3415 // - The codecs provided by the engine is usable by Channel.
3416 // It does not check that the codecs in the RecvParameters are actually
3417 // what we sent in - though it's probably reasonable to expect so, if
3418 // SetRecvParameters returns true.
3419 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003420 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3421 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003422 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003423 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003424 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003425 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003426 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003427 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003428 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003429 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3430 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003431 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003432 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003433 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003434}
ossu9def8002017-02-09 05:14:32 -08003435
3436TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3437 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003438 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3439 {48000, 2, 16000, 10000, 20000}};
3440 spec1.info.allow_comfort_noise = false;
3441 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003442 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003443 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3444 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003445 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003446 specs.push_back(webrtc::AudioCodecSpec{
3447 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3448 {16000, 1, 13300}});
3449 specs.push_back(
3450 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3451 specs.push_back(
3452 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003453
ossueb1fde42017-05-02 06:46:30 -07003454 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3455 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3456 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003457 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003458 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003459 .WillOnce(Return(specs));
3460
peaha9cc40b2017-06-29 08:32:09 -07003461 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3462 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003463 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003464 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003465 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003466 auto codecs = engine.recv_codecs();
3467 EXPECT_EQ(11, codecs.size());
3468
3469 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3470 // check the actual values safely, to provide better test results.
3471 auto get_codec =
3472 [&codecs](size_t index) -> const cricket::AudioCodec& {
3473 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3474 if (codecs.size() > index)
3475 return codecs[index];
3476 return missing_codec;
3477 };
3478
3479 // Ensure the general codecs are generated first and in order.
3480 for (size_t i = 0; i != specs.size(); ++i) {
3481 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3482 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3483 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3484 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3485 }
3486
3487 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003488 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003489 auto find_codec =
3490 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3491 for (size_t i = 0; i != codecs.size(); ++i) {
3492 const cricket::AudioCodec& codec = codecs[i];
3493 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3494 codec.clockrate == format.clockrate_hz &&
3495 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003496 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003497 }
3498 }
3499 return -1;
3500 };
3501
3502 // Ensure all supplementary codecs are generated last. Their internal ordering
3503 // is not important.
3504 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3505 const int num_specs = static_cast<int>(specs.size());
3506 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3507 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3508 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3509 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3510 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3511 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3512 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3513}