blob: 28d09e8af9bf9853b93a861c98ca0d7eab6f14d9 [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;
604 stats.accelerate_rate = 4.56f;
605 stats.preemptive_expand_rate = 7.89f;
606 stats.decoding_calls_to_silence_generator = 12;
607 stats.decoding_calls_to_neteq = 345;
608 stats.decoding_normal = 67890;
609 stats.decoding_plc = 1234;
610 stats.decoding_cng = 5678;
611 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700612 stats.decoding_muted_output = 3456;
613 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200614 return stats;
615 }
616 void SetAudioReceiveStreamStats() {
617 for (auto* s : call_.GetAudioReceiveStreams()) {
618 s->SetStats(GetAudioReceiveStreamStats());
619 }
620 }
621 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700622 const auto stats = GetAudioReceiveStreamStats();
623 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
624 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
625 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
626 EXPECT_EQ(info.packets_lost, stats.packets_lost);
627 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
628 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800629 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700630 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
631 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
632 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200633 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700634 stats.jitter_buffer_preferred_ms);
635 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
636 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700637 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
638 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
solenberg85a04962015-10-27 03:35:21 -0700639 EXPECT_EQ(info.expand_rate, stats.expand_rate);
640 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
641 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
642 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
643 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200644 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700645 stats.decoding_calls_to_silence_generator);
646 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
647 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
648 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
649 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
650 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700651 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700652 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200653 }
hbos1acfbd22016-11-17 23:43:29 -0800654 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
655 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
656 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
657 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
658 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
659 codec.ToCodecParameters());
660 }
661 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
662 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
663 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
664 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
665 codec.ToCodecParameters());
666 }
667 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200668
peah8271d042016-11-22 07:24:52 -0800669 bool IsHighPassFilterEnabled() {
670 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
671 }
672
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700674 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700675 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800676 webrtc::test::MockGainControl& apm_gc_;
677 webrtc::test::MockEchoCancellation& apm_ec_;
678 webrtc::test::MockNoiseSuppression& apm_ns_;
679 webrtc::test::MockVoiceDetection& apm_vd_;
680 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700681 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200682 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000683 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700684 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700685 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200686 cricket::AudioSendParameters send_parameters_;
687 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800688 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700689 webrtc::AudioProcessing::Config apm_config_;
690
stefanba4c0e42016-02-04 04:12:24 -0800691 private:
692 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693};
694
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695// Tests that we can create and destroy a channel.
696TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700697 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698}
699
solenberg31fec402016-05-06 02:13:12 -0700700// Test that we can add a send stream and that it has the correct defaults.
701TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
702 EXPECT_TRUE(SetupChannel());
703 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800704 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
705 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
706 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700707 EXPECT_EQ("", config.rtp.c_name);
708 EXPECT_EQ(0u, config.rtp.extensions.size());
709 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
710 config.send_transport);
711}
712
713// Test that we can add a receive stream and that it has the correct defaults.
714TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
715 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800716 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700717 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800718 GetRecvStreamConfig(kSsrcX);
719 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700720 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
721 EXPECT_FALSE(config.rtp.transport_cc);
722 EXPECT_EQ(0u, config.rtp.extensions.size());
723 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
724 config.rtcp_send_transport);
725 EXPECT_EQ("", config.sync_group);
726}
727
stefanba4c0e42016-02-04 04:12:24 -0800728TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700729 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800730 bool opus_found = false;
731 for (cricket::AudioCodec codec : codecs) {
732 if (codec.name == "opus") {
733 EXPECT_TRUE(HasTransportCc(codec));
734 opus_found = true;
735 }
736 }
737 EXPECT_TRUE(opus_found);
738}
739
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740// Test that we set our inbound codecs properly, including changing PT.
741TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700742 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200743 cricket::AudioRecvParameters parameters;
744 parameters.codecs.push_back(kIsacCodec);
745 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800746 parameters.codecs.push_back(kTelephoneEventCodec1);
747 parameters.codecs.push_back(kTelephoneEventCodec2);
748 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200749 parameters.codecs[2].id = 126;
750 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800751 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700752 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
753 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
754 {{0, {"PCMU", 8000, 1}},
755 {106, {"ISAC", 16000, 1}},
756 {126, {"telephone-event", 8000, 1}},
757 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758}
759
760// Test that we fail to set an unknown inbound codec.
761TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700762 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200763 cricket::AudioRecvParameters parameters;
764 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700765 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200766 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767}
768
769// Test that we fail if we have duplicate types in the inbound list.
770TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700771 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200772 cricket::AudioRecvParameters parameters;
773 parameters.codecs.push_back(kIsacCodec);
774 parameters.codecs.push_back(kCn16000Codec);
775 parameters.codecs[1].id = kIsacCodec.id;
776 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777}
778
779// Test that we can decode OPUS without stereo parameters.
780TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700781 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200782 cricket::AudioRecvParameters parameters;
783 parameters.codecs.push_back(kIsacCodec);
784 parameters.codecs.push_back(kPcmuCodec);
785 parameters.codecs.push_back(kOpusCodec);
786 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800787 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700788 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
789 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
790 {{0, {"PCMU", 8000, 1}},
791 {103, {"ISAC", 16000, 1}},
792 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793}
794
795// Test that we can decode OPUS with stereo = 0.
796TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700797 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200798 cricket::AudioRecvParameters parameters;
799 parameters.codecs.push_back(kIsacCodec);
800 parameters.codecs.push_back(kPcmuCodec);
801 parameters.codecs.push_back(kOpusCodec);
802 parameters.codecs[2].params["stereo"] = "0";
803 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800804 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700805 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
806 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
807 {{0, {"PCMU", 8000, 1}},
808 {103, {"ISAC", 16000, 1}},
809 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810}
811
812// Test that we can decode OPUS with stereo = 1.
813TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700814 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200815 cricket::AudioRecvParameters parameters;
816 parameters.codecs.push_back(kIsacCodec);
817 parameters.codecs.push_back(kPcmuCodec);
818 parameters.codecs.push_back(kOpusCodec);
819 parameters.codecs[2].params["stereo"] = "1";
820 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800821 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700822 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
823 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
824 {{0, {"PCMU", 8000, 1}},
825 {103, {"ISAC", 16000, 1}},
826 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827}
828
829// Test that changes to recv codecs are applied to all streams.
830TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700831 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200832 cricket::AudioRecvParameters parameters;
833 parameters.codecs.push_back(kIsacCodec);
834 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800835 parameters.codecs.push_back(kTelephoneEventCodec1);
836 parameters.codecs.push_back(kTelephoneEventCodec2);
837 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200838 parameters.codecs[2].id = 126;
839 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700840 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
841 EXPECT_TRUE(AddRecvStream(ssrc));
842 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
843 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
844 {{0, {"PCMU", 8000, 1}},
845 {106, {"ISAC", 16000, 1}},
846 {126, {"telephone-event", 8000, 1}},
847 {107, {"telephone-event", 32000, 1}}})));
848 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849}
850
851TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700852 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200853 cricket::AudioRecvParameters parameters;
854 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800855 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000857
solenberg2100c0b2017-03-01 11:29:29 -0800858 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800859 ASSERT_EQ(1, dm.count(106));
860 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000861}
862
863// Test that we can apply the same set of codecs again while playing.
864TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700865 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200866 cricket::AudioRecvParameters parameters;
867 parameters.codecs.push_back(kIsacCodec);
868 parameters.codecs.push_back(kCn16000Codec);
869 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700870 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872
deadbeefcb383672017-04-26 16:28:42 -0700873 // Remapping a payload type to a different codec should fail.
874 parameters.codecs[0] = kOpusCodec;
875 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200876 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800877 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878}
879
880// Test that we can add a codec while playing.
881TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700882 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200883 cricket::AudioRecvParameters parameters;
884 parameters.codecs.push_back(kIsacCodec);
885 parameters.codecs.push_back(kCn16000Codec);
886 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700887 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 parameters.codecs.push_back(kOpusCodec);
890 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800891 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
deadbeefcb383672017-04-26 16:28:42 -0700894// Test that we accept adding the same codec with a different payload type.
895// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
896TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
897 EXPECT_TRUE(SetupRecvStream());
898 cricket::AudioRecvParameters parameters;
899 parameters.codecs.push_back(kIsacCodec);
900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
901
902 ++parameters.codecs[0].id;
903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
904}
905
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700907 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000909 // Test that when autobw is enabled, bitrate is kept as the default
910 // value. autobw is enabled for the following tests because the target
911 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912
913 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700914 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
916 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700917 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
ossu20a4b3f2017-04-27 02:08:52 -0700919 // opus, default bitrate == 32000 in mono.
920 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921}
922
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000923TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700924 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700927 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
928 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700929 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700932 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
933 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
934 // Rates above the max (510000) should be capped.
935 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936}
937
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000938TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700939 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940
941 // Test that we can only set a maximum bitrate for a fixed-rate codec
942 // if it's bigger than the fixed rate.
943
944 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
946 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
947 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
948 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
949 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
950 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
951 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000952}
953
954TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200956 const int kDesiredBitrate = 128000;
957 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700958 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200959 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700960 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000961
962 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800963 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000964
solenberg2100c0b2017-03-01 11:29:29 -0800965 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000966}
967
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968// Test that bitrate cannot be set for CBR codecs.
969// Bitrate is ignored if it is higher than the fixed bitrate.
970// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700972 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973
974 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700975 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800976 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200977
978 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700979 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800980 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200981
982 send_parameters_.max_bandwidth_bps = 128;
983 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800984 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985}
986
skvlade0d46372016-04-07 22:59:22 -0700987// Test that the per-stream bitrate limit and the global
988// bitrate limit both apply.
989TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
990 EXPECT_TRUE(SetupSendStream());
991
ossu20a4b3f2017-04-27 02:08:52 -0700992 // opus, default bitrate == 32000.
993 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700994 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
995 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
996 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
997
998 // CBR codecs allow both maximums to exceed the bitrate.
999 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1000 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1001 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1002 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1003
1004 // CBR codecs don't allow per stream maximums to be too low.
1005 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1006 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1007}
1008
1009// Test that an attempt to set RtpParameters for a stream that does not exist
1010// fails.
1011TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1012 EXPECT_TRUE(SetupChannel());
1013 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001014 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001015 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1016
1017 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001018 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001019}
1020
1021TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001022 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001023 // This test verifies that setting RtpParameters succeeds only if
1024 // the structure contains exactly one encoding.
1025 // TODO(skvlad): Update this test when we start supporting setting parameters
1026 // for each encoding individually.
1027
1028 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001029 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001030 // Two or more encodings should result in failure.
1031 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001032 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001033 // Zero encodings should also fail.
1034 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001035 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001036}
1037
1038// Changing the SSRC through RtpParameters is not allowed.
1039TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1040 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001041 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001042 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001043 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001044}
1045
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001046// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001047// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001048TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1049 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001050 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001051 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001052 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001053 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001054 ASSERT_EQ(1u, parameters.encodings.size());
1055 ASSERT_TRUE(parameters.encodings[0].active);
1056 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001057 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1058 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001059
1060 // Now change it back to active and verify we resume sending.
1061 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001062 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1063 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001064}
1065
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001066// Test that SetRtpSendParameters configures the correct encoding channel for
1067// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001068TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1069 SetupForMultiSendStream();
1070 // Create send streams.
1071 for (uint32_t ssrc : kSsrcs4) {
1072 EXPECT_TRUE(
1073 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1074 }
1075 // Configure one stream to be limited by the stream config, another to be
1076 // limited by the global max, and the third one with no per-stream limit
1077 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001078 SetGlobalMaxBitrate(kOpusCodec, 32000);
1079 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1080 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001081 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1082
ossu20a4b3f2017-04-27 02:08:52 -07001083 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1084 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1085 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001086
1087 // Remove the global cap; the streams should switch to their respective
1088 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001089 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001090 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1091 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1092 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001093}
1094
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001095// Test that GetRtpSendParameters returns the currently configured codecs.
1096TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001097 EXPECT_TRUE(SetupSendStream());
1098 cricket::AudioSendParameters parameters;
1099 parameters.codecs.push_back(kIsacCodec);
1100 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001101 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001102
solenberg2100c0b2017-03-01 11:29:29 -08001103 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001104 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001105 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1106 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001107}
1108
deadbeefcb443432016-12-12 11:12:36 -08001109// Test that GetRtpSendParameters returns an SSRC.
1110TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1111 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001112 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001113 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001114 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001115}
1116
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001117// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001118TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001119 EXPECT_TRUE(SetupSendStream());
1120 cricket::AudioSendParameters parameters;
1121 parameters.codecs.push_back(kIsacCodec);
1122 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001123 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001124
solenberg2100c0b2017-03-01 11:29:29 -08001125 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001126
1127 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001128 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001129
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001130 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1132 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133}
1134
minyuececec102017-03-27 13:04:25 -07001135// Test that max_bitrate_bps in send stream config gets updated correctly when
1136// SetRtpSendParameters is called.
1137TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1138 webrtc::test::ScopedFieldTrials override_field_trials(
1139 "WebRTC-Audio-SendSideBwe/Enabled/");
1140 EXPECT_TRUE(SetupSendStream());
1141 cricket::AudioSendParameters send_parameters;
1142 send_parameters.codecs.push_back(kOpusCodec);
1143 SetSendParameters(send_parameters);
1144
1145 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1146 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1147 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1148
1149 constexpr int kMaxBitrateBps = 6000;
1150 rtp_parameters.encodings[0].max_bitrate_bps =
1151 rtc::Optional<int>(kMaxBitrateBps);
1152 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1153
1154 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1155 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1156}
1157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158// Test that GetRtpReceiveParameters returns the currently configured codecs.
1159TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1160 EXPECT_TRUE(SetupRecvStream());
1161 cricket::AudioRecvParameters parameters;
1162 parameters.codecs.push_back(kIsacCodec);
1163 parameters.codecs.push_back(kPcmuCodec);
1164 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1165
1166 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001167 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001168 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1169 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1170 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1171}
1172
deadbeefcb443432016-12-12 11:12:36 -08001173// Test that GetRtpReceiveParameters returns an SSRC.
1174TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1175 EXPECT_TRUE(SetupRecvStream());
1176 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001177 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001178 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001179 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001180}
1181
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001182// Test that if we set/get parameters multiple times, we get the same results.
1183TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1184 EXPECT_TRUE(SetupRecvStream());
1185 cricket::AudioRecvParameters parameters;
1186 parameters.codecs.push_back(kIsacCodec);
1187 parameters.codecs.push_back(kPcmuCodec);
1188 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1189
1190 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001191 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001192
1193 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001194 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001195
1196 // ... And this shouldn't change the params returned by
1197 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001198 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1199 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001200}
1201
deadbeef3bc15102017-04-20 19:25:07 -07001202// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1203// aren't signaled. It should return an empty "RtpEncodingParameters" when
1204// configured to receive an unsignaled stream and no packets have been received
1205// yet, and start returning the SSRC once a packet has been received.
1206TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1207 ASSERT_TRUE(SetupChannel());
1208 // Call necessary methods to configure receiving a default stream as
1209 // soon as it arrives.
1210 cricket::AudioRecvParameters parameters;
1211 parameters.codecs.push_back(kIsacCodec);
1212 parameters.codecs.push_back(kPcmuCodec);
1213 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1214
1215 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1216 // stream. Should return nothing.
1217 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1218
1219 // Set a sink for an unsignaled stream.
1220 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1221 // Value of "0" means "unsignaled stream".
1222 channel_->SetRawAudioSink(0, std::move(fake_sink));
1223
1224 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1225 // in this method means "unsignaled stream".
1226 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1227 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1228 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1229
1230 // Receive PCMU packet (SSRC=1).
1231 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1232
1233 // The |ssrc| member should still be unset.
1234 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1235 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1236 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1237}
1238
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001239// Test that we apply codecs properly.
1240TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001241 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001242 cricket::AudioSendParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001245 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001246 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001247 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001248 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001249 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1250 EXPECT_EQ(96, send_codec_spec.payload_type);
1251 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1252 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1253 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1254 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001255 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001256}
1257
ossu20a4b3f2017-04-27 02:08:52 -07001258// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1259// AudioSendStream.
1260TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001261 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001262 cricket::AudioSendParameters parameters;
1263 parameters.codecs.push_back(kIsacCodec);
1264 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001265 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001266 parameters.codecs[0].id = 96;
1267 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001268 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001269 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001270 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001271 // Calling SetSendCodec again with same codec which is already set.
1272 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001273 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001274 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001275}
1276
ossu20a4b3f2017-04-27 02:08:52 -07001277// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1278// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001279
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001280// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001281TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001282 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001283 cricket::AudioSendParameters parameters;
1284 parameters.codecs.push_back(kOpusCodec);
1285 parameters.codecs[0].bitrate = 0;
1286 parameters.codecs[0].clockrate = 50000;
1287 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001288}
1289
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001290// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001292 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001293 cricket::AudioSendParameters parameters;
1294 parameters.codecs.push_back(kOpusCodec);
1295 parameters.codecs[0].bitrate = 0;
1296 parameters.codecs[0].channels = 0;
1297 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001298}
1299
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001300// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001302 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001303 cricket::AudioSendParameters parameters;
1304 parameters.codecs.push_back(kOpusCodec);
1305 parameters.codecs[0].bitrate = 0;
1306 parameters.codecs[0].channels = 0;
1307 parameters.codecs[0].params["stereo"] = "1";
1308 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001309}
1310
1311// Test that if channel is 1 for opus and there's no stereo, we fail.
1312TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001313 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001314 cricket::AudioSendParameters parameters;
1315 parameters.codecs.push_back(kOpusCodec);
1316 parameters.codecs[0].bitrate = 0;
1317 parameters.codecs[0].channels = 1;
1318 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319}
1320
1321// Test that if channel is 1 for opus and stereo=0, we fail.
1322TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001323 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001324 cricket::AudioSendParameters parameters;
1325 parameters.codecs.push_back(kOpusCodec);
1326 parameters.codecs[0].bitrate = 0;
1327 parameters.codecs[0].channels = 1;
1328 parameters.codecs[0].params["stereo"] = "0";
1329 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330}
1331
1332// Test that if channel is 1 for opus and stereo=1, we fail.
1333TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001334 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001335 cricket::AudioSendParameters parameters;
1336 parameters.codecs.push_back(kOpusCodec);
1337 parameters.codecs[0].bitrate = 0;
1338 parameters.codecs[0].channels = 1;
1339 parameters.codecs[0].params["stereo"] = "1";
1340 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341}
1342
ossu20a4b3f2017-04-27 02:08:52 -07001343// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kOpusCodec);
1348 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001349 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001350 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351}
1352
ossu20a4b3f2017-04-27 02:08:52 -07001353// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001355 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001356 cricket::AudioSendParameters parameters;
1357 parameters.codecs.push_back(kOpusCodec);
1358 parameters.codecs[0].bitrate = 0;
1359 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001360 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001361 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
ossu20a4b3f2017-04-27 02:08:52 -07001364// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001365TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kOpusCodec);
1369 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001370 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001372 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001373 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001374
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001375 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001376 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001377 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001378}
1379
ossu20a4b3f2017-04-27 02:08:52 -07001380// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001382 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001383 cricket::AudioSendParameters parameters;
1384 parameters.codecs.push_back(kOpusCodec);
1385 parameters.codecs[0].bitrate = 0;
1386 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001387 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001388 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389}
1390
ossu20a4b3f2017-04-27 02:08:52 -07001391// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001392TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001393 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 cricket::AudioSendParameters parameters;
1395 parameters.codecs.push_back(kOpusCodec);
1396 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001397 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001399 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001400 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001401
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001403 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001404 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001405}
1406
ossu20a4b3f2017-04-27 02:08:52 -07001407// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001409 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 cricket::AudioSendParameters parameters;
1411 parameters.codecs.push_back(kOpusCodec);
1412 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001414 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1415 EXPECT_EQ(111, spec.payload_type);
1416 EXPECT_EQ(96000, spec.target_bitrate_bps);
1417 EXPECT_EQ("opus", spec.format.name);
1418 EXPECT_EQ(2, spec.format.num_channels);
1419 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001420}
1421
ossu20a4b3f2017-04-27 02:08:52 -07001422// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kOpusCodec);
1427 parameters.codecs[0].bitrate = 30000;
1428 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001430 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001431}
1432
ossu20a4b3f2017-04-27 02:08:52 -07001433// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kOpusCodec);
1438 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001439 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001440 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441}
1442
ossu20a4b3f2017-04-27 02:08:52 -07001443// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001445 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001446 cricket::AudioSendParameters parameters;
1447 parameters.codecs.push_back(kOpusCodec);
1448 parameters.codecs[0].bitrate = 30000;
1449 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001450 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001451 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001452}
1453
stefan13f1a0a2016-11-30 07:22:58 -08001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1455 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1456 200000);
1457}
1458
1459TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1460 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1461}
1462
1463TEST_F(WebRtcVoiceEngineTestFake,
1464 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1465 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1466}
1467
1468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1469 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1470}
1471
1472TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001473 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001474 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1475 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001476 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001477 SetSendParameters(send_parameters_);
1478 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1479 << "Setting max bitrate should keep previous min bitrate.";
1480 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1481 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001482 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001483}
1484
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001485// Test that we can enable NACK with opus as caller.
1486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001487 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001488 cricket::AudioSendParameters parameters;
1489 parameters.codecs.push_back(kOpusCodec);
1490 parameters.codecs[0].AddFeedbackParam(
1491 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1492 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001493 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001494 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001495 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001496}
1497
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001498// Test that we can enable NACK with opus as callee.
1499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001500 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001501 cricket::AudioSendParameters parameters;
1502 parameters.codecs.push_back(kOpusCodec);
1503 parameters.codecs[0].AddFeedbackParam(
1504 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1505 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001506 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001507 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001508 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001509 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001510
1511 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001512 cricket::StreamParams::CreateLegacy(kSsrcX)));
1513 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001514}
1515
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516// Test that we can enable NACK on receive streams.
1517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001519 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001520 cricket::AudioSendParameters parameters;
1521 parameters.codecs.push_back(kOpusCodec);
1522 parameters.codecs[0].AddFeedbackParam(
1523 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1524 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001525 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1526 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001527 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001528 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1529 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001530}
1531
1532// Test that we can disable NACK.
1533TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001534 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 cricket::AudioSendParameters parameters;
1536 parameters.codecs.push_back(kOpusCodec);
1537 parameters.codecs[0].AddFeedbackParam(
1538 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1539 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001543 parameters.codecs.clear();
1544 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001546 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
1549// Test that we can disable NACK on receive streams.
1550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001551 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].AddFeedbackParam(
1556 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1557 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001558 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1560 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001562 parameters.codecs.clear();
1563 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001564 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001565 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1566 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001567}
1568
1569// Test that NACK is enabled on a new receive stream.
1570TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001571 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001572 cricket::AudioSendParameters parameters;
1573 parameters.codecs.push_back(kIsacCodec);
1574 parameters.codecs.push_back(kCn16000Codec);
1575 parameters.codecs[0].AddFeedbackParam(
1576 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1577 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001579 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001580
solenberg2100c0b2017-03-01 11:29:29 -08001581 EXPECT_TRUE(AddRecvStream(kSsrcY));
1582 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1583 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1584 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585}
1586
stefanba4c0e42016-02-04 04:12:24 -08001587TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001588 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001589 cricket::AudioSendParameters send_parameters;
1590 send_parameters.codecs.push_back(kOpusCodec);
1591 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001592 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001593
1594 cricket::AudioRecvParameters recv_parameters;
1595 recv_parameters.codecs.push_back(kIsacCodec);
1596 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_TRUE(AddRecvStream(kSsrcX));
1598 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001599 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001600 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001601
ossudedfd282016-06-14 07:12:39 -07001602 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001605 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001606 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001607}
1608
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001609// Test that we can switch back and forth between Opus and ISAC with CN.
1610TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001611 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001612
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001613 cricket::AudioSendParameters opus_parameters;
1614 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001615 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001616 {
ossu20a4b3f2017-04-27 02:08:52 -07001617 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1618 EXPECT_EQ(111, spec.payload_type);
1619 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001620 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001622 cricket::AudioSendParameters isac_parameters;
1623 isac_parameters.codecs.push_back(kIsacCodec);
1624 isac_parameters.codecs.push_back(kCn16000Codec);
1625 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001626 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001627 {
ossu20a4b3f2017-04-27 02:08:52 -07001628 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1629 EXPECT_EQ(103, spec.payload_type);
1630 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001631 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632
solenberg059fb442016-10-26 05:12:24 -07001633 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001634 {
ossu20a4b3f2017-04-27 02:08:52 -07001635 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1636 EXPECT_EQ(111, spec.payload_type);
1637 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001638 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001639}
1640
1641// Test that we handle various ways of specifying bitrate.
1642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters parameters;
1645 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001647 {
ossu20a4b3f2017-04-27 02:08:52 -07001648 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1649 EXPECT_EQ(103, spec.payload_type);
1650 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1651 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001652 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001653
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001655 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001656 {
ossu20a4b3f2017-04-27 02:08:52 -07001657 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1658 EXPECT_EQ(103, spec.payload_type);
1659 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1660 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001661 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001663 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001664 {
ossu20a4b3f2017-04-27 02:08:52 -07001665 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1666 EXPECT_EQ(103, spec.payload_type);
1667 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1668 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001669 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001673 {
ossu20a4b3f2017-04-27 02:08:52 -07001674 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1675 EXPECT_EQ(0, spec.payload_type);
1676 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1677 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001678 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001681 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001682 {
ossu20a4b3f2017-04-27 02:08:52 -07001683 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1684 EXPECT_EQ(0, spec.payload_type);
1685 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1686 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001687 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 parameters.codecs[0] = kOpusCodec;
1690 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001691 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001692 {
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(111, spec.payload_type);
1695 EXPECT_STREQ("opus", spec.format.name.c_str());
1696 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001697 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698}
1699
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001700// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001702 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 cricket::AudioSendParameters parameters;
1704 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001705}
1706
1707// Test that we can set send codecs even with telephone-event codec as the first
1708// one on the list.
1709TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001712 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001713 parameters.codecs.push_back(kIsacCodec);
1714 parameters.codecs.push_back(kPcmuCodec);
1715 parameters.codecs[0].id = 98; // DTMF
1716 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001717 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001718 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1719 EXPECT_EQ(96, spec.payload_type);
1720 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001721 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001722}
1723
solenberg31642aa2016-03-14 08:00:37 -07001724// Test that payload type range is limited for telephone-event codec.
1725TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001726 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001727 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001728 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001729 parameters.codecs.push_back(kIsacCodec);
1730 parameters.codecs[0].id = 0; // DTMF
1731 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001733 EXPECT_TRUE(channel_->CanInsertDtmf());
1734 parameters.codecs[0].id = 128; // DTMF
1735 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1736 EXPECT_FALSE(channel_->CanInsertDtmf());
1737 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001739 EXPECT_TRUE(channel_->CanInsertDtmf());
1740 parameters.codecs[0].id = -1; // DTMF
1741 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1742 EXPECT_FALSE(channel_->CanInsertDtmf());
1743}
1744
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001745// Test that we can set send codecs even with CN codec as the first
1746// one on the list.
1747TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001748 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters parameters;
1750 parameters.codecs.push_back(kCn16000Codec);
1751 parameters.codecs.push_back(kIsacCodec);
1752 parameters.codecs.push_back(kPcmuCodec);
1753 parameters.codecs[0].id = 98; // wideband CN
1754 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001756 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1757 EXPECT_EQ(96, send_codec_spec.payload_type);
1758 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001759 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760}
1761
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001762// Test that we set VAD and DTMF types correctly as caller.
1763TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001764 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 cricket::AudioSendParameters parameters;
1766 parameters.codecs.push_back(kIsacCodec);
1767 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001769 parameters.codecs.push_back(kCn16000Codec);
1770 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001771 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001772 parameters.codecs[0].id = 96;
1773 parameters.codecs[2].id = 97; // wideband CN
1774 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001776 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1777 EXPECT_EQ(96, send_codec_spec.payload_type);
1778 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1779 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001780 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001781 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001782}
1783
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001784// Test that we set VAD and DTMF types correctly as callee.
1785TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001786 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 cricket::AudioSendParameters parameters;
1788 parameters.codecs.push_back(kIsacCodec);
1789 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001790 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001791 parameters.codecs.push_back(kCn16000Codec);
1792 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001793 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001794 parameters.codecs[0].id = 96;
1795 parameters.codecs[2].id = 97; // wideband CN
1796 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001797 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001798 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001799 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001800
ossu20a4b3f2017-04-27 02:08:52 -07001801 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1802 EXPECT_EQ(96, send_codec_spec.payload_type);
1803 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1804 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001805 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001806 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001807}
1808
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809// Test that we only apply VAD if we have a CN codec that matches the
1810// send codec clockrate.
1811TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001812 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001815 parameters.codecs.push_back(kIsacCodec);
1816 parameters.codecs.push_back(kCn16000Codec);
1817 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001818 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001819 {
ossu20a4b3f2017-04-27 02:08:52 -07001820 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1821 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1822 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001823 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001824 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001827 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001828 {
ossu20a4b3f2017-04-27 02:08:52 -07001829 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1830 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1831 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001832 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001833 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001834 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001836 {
ossu20a4b3f2017-04-27 02:08:52 -07001837 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1838 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1839 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001840 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001841 }
Brave Yao5225dd82015-03-26 07:39:19 +08001842 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001845 {
ossu20a4b3f2017-04-27 02:08:52 -07001846 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1847 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1848 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001849 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001850}
1851
1852// Test that we perform case-insensitive matching of codec names.
1853TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001854 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001855 cricket::AudioSendParameters parameters;
1856 parameters.codecs.push_back(kIsacCodec);
1857 parameters.codecs.push_back(kPcmuCodec);
1858 parameters.codecs.push_back(kCn16000Codec);
1859 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001860 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001861 parameters.codecs[0].name = "iSaC";
1862 parameters.codecs[0].id = 96;
1863 parameters.codecs[2].id = 97; // wideband CN
1864 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001865 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001866 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1867 EXPECT_EQ(96, send_codec_spec.payload_type);
1868 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1869 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001870 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001871 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001872}
1873
stefanba4c0e42016-02-04 04:12:24 -08001874class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1875 public:
1876 WebRtcVoiceEngineWithSendSideBweTest()
1877 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1878};
1879
1880TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1881 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001882 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001883 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001884 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1885 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1886 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001887 extension.id);
1888 return;
1889 }
1890 }
1891 FAIL() << "Transport sequence number extension not in header-extension list.";
1892}
1893
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001894// Test support for audio level header extension.
1895TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001896 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001897}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001898TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001899 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001900}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001901
solenbergd4adce42016-11-17 06:26:52 -08001902// Test support for transport sequence number header extension.
1903TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1904 TestSetSendRtpHeaderExtensions(
1905 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001906}
solenbergd4adce42016-11-17 06:26:52 -08001907TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1908 TestSetRecvRtpHeaderExtensions(
1909 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910}
1911
solenberg1ac56142015-10-13 03:58:19 -07001912// Test that we can create a channel and start sending on it.
1913TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001914 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(send_parameters_);
1916 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001917 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001918 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001919 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001920}
1921
1922// Test that a channel will send if and only if it has a source and is enabled
1923// for sending.
1924TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001925 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001926 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001927 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001928 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001929 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1930 SetAudioSend(kSsrcX, true, &fake_source_);
1931 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1932 SetAudioSend(kSsrcX, true, nullptr);
1933 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001934}
1935
solenberg94218532016-06-16 10:53:22 -07001936// Test that a channel is muted/unmuted.
1937TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1938 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001939 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001940 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1941 SetAudioSend(kSsrcX, true, nullptr);
1942 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1943 SetAudioSend(kSsrcX, false, nullptr);
1944 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001945}
1946
solenberg6d6e7c52016-04-13 09:07:30 -07001947// Test that SetSendParameters() does not alter a stream's send state.
1948TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1949 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001950 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001951
1952 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001953 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001954 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001955
1956 // Changing RTP header extensions will recreate the AudioSendStream.
1957 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001958 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001960 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001961
1962 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001963 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001964 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001965
1966 // Changing RTP header extensions will recreate the AudioSendStream.
1967 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001968 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001969 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001970}
1971
solenberg1ac56142015-10-13 03:58:19 -07001972// Test that we can create a channel and start playing out on it.
1973TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001974 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001975 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001976 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001977 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001978 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001979 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001980}
1981
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001982// Test that we can add and remove send streams.
1983TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1984 SetupForMultiSendStream();
1985
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001986 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001987 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001988
solenbergc96df772015-10-21 13:01:53 -07001989 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001990 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001991 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001992 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001993 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001994 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 }
tfarina5237aaf2015-11-10 23:44:30 -08001996 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001997
solenbergc96df772015-10-21 13:01:53 -07001998 // Delete the send streams.
1999 for (uint32_t ssrc : kSsrcs4) {
2000 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002001 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002002 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002003 }
solenbergc96df772015-10-21 13:01:53 -07002004 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002005}
2006
2007// Test SetSendCodecs correctly configure the codecs in all send streams.
2008TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2009 SetupForMultiSendStream();
2010
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002011 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002012 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002014 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015 }
2016
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002017 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002018 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 parameters.codecs.push_back(kIsacCodec);
2020 parameters.codecs.push_back(kCn16000Codec);
2021 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002022 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023
2024 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002025 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002026 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2027 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002028 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2029 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2030 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002031 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002032 }
2033
minyue7a973442016-10-20 03:27:12 -07002034 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002035 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002036 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002037 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002038 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2039 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002040 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2041 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2042 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 }
2044}
2045
2046// Test we can SetSend on all send streams correctly.
2047TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2048 SetupForMultiSendStream();
2049
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002050 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002051 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002053 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002054 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002055 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002056 }
2057
2058 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002059 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002060 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002062 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 }
2064
2065 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002066 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002067 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002069 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070 }
2071}
2072
2073// Test we can set the correct statistics on all send streams.
2074TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2075 SetupForMultiSendStream();
2076
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002077 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002078 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002080 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002081 }
solenberg85a04962015-10-27 03:35:21 -07002082
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002083 // Create a receive stream to check that none of the send streams end up in
2084 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002085 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002086
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002088 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002089 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002090 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002091
solenberg85a04962015-10-27 03:35:21 -07002092 // Check stats for the added streams.
2093 {
2094 cricket::VoiceMediaInfo info;
2095 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096
solenberg85a04962015-10-27 03:35:21 -07002097 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002098 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002099 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002100 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002101 }
hbos1acfbd22016-11-17 23:43:29 -08002102 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002103
2104 // We have added one receive stream. We should see empty stats.
2105 EXPECT_EQ(info.receivers.size(), 1u);
2106 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107 }
solenberg1ac56142015-10-13 03:58:19 -07002108
solenberg2100c0b2017-03-01 11:29:29 -08002109 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002110 {
2111 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002113 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002114 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002115 EXPECT_EQ(0u, info.receivers.size());
2116 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002117
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002118 // Deliver a new packet - a default receive stream should be created and we
2119 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002120 {
2121 cricket::VoiceMediaInfo info;
2122 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2123 SetAudioReceiveStreamStats();
2124 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002125 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002126 EXPECT_EQ(1u, info.receivers.size());
2127 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002128 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002129 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002130}
2131
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002132// Test that we can add and remove receive streams, and do proper send/playout.
2133// We can receive on multiple streams while sending one stream.
2134TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002135 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002136
solenberg1ac56142015-10-13 03:58:19 -07002137 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002138 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002139 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140
solenberg1ac56142015-10-13 03:58:19 -07002141 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002142 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002143 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145
solenberg1ac56142015-10-13 03:58:19 -07002146 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002147 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148
2149 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002150 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2151 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2152 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153
2154 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002155 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002156 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157
2158 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002159 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002160 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2161 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002162
aleloi84ef6152016-08-04 05:28:21 -07002163 // Restart playout and make sure recv streams are played out.
2164 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002165 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2166 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167
aleloi84ef6152016-08-04 05:28:21 -07002168 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002169 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2170 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171}
2172
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002173// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002174// and start sending on it.
2175TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002176 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002177 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2178 EXPECT_CALL(apm_gc_,
2179 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002180 SetSendParameters(send_parameters_);
2181 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002183 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002184 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185}
2186
wu@webrtc.org97077a32013-10-25 21:18:33 +00002187TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002188 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002189 EXPECT_CALL(adm_,
2190 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002191 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2192 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002193 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2194 send_parameters_.options.tx_agc_digital_compression_gain =
2195 rtc::Optional<uint16_t>(9);
2196 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2197 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002198 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2199 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2200 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002201 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002202
2203 // Check interaction with adjust_agc_delta. Both should be respected, for
2204 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002205 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002206 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002207 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002208}
2209
wu@webrtc.org97077a32013-10-25 21:18:33 +00002210TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002211 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002212 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2213 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002214 send_parameters_.options.recording_sample_rate =
2215 rtc::Optional<uint32_t>(48000);
2216 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002217 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002218}
2219
minyue6b825df2016-10-31 04:08:32 -07002220TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2221 EXPECT_TRUE(SetupSendStream());
2222 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2223 send_parameters_.options.audio_network_adaptor_config =
2224 rtc::Optional<std::string>("1234");
2225 SetSendParameters(send_parameters_);
2226 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002227 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002228}
2229
2230TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2231 EXPECT_TRUE(SetupSendStream());
2232 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2233 send_parameters_.options.audio_network_adaptor_config =
2234 rtc::Optional<std::string>("1234");
2235 SetSendParameters(send_parameters_);
2236 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002237 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002238 cricket::AudioOptions options;
2239 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002240 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002241 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002242}
2243
2244TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2245 EXPECT_TRUE(SetupSendStream());
2246 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2247 send_parameters_.options.audio_network_adaptor_config =
2248 rtc::Optional<std::string>("1234");
2249 SetSendParameters(send_parameters_);
2250 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002251 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002252 const int initial_num = call_.GetNumCreatedSendStreams();
2253 cricket::AudioOptions options;
2254 options.audio_network_adaptor = rtc::Optional<bool>();
2255 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2256 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002257 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002258 // AudioSendStream not expected to be recreated.
2259 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2260 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002261 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002262}
2263
michaelt6672b262017-01-11 10:17:59 -08002264class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2265 : public WebRtcVoiceEngineTestFake {
2266 public:
2267 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2268 : WebRtcVoiceEngineTestFake(
2269 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2270 "Enabled/") {}
2271};
2272
2273TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2274 EXPECT_TRUE(SetupSendStream());
2275 cricket::AudioSendParameters parameters;
2276 parameters.codecs.push_back(kOpusCodec);
2277 SetSendParameters(parameters);
2278 const int initial_num = call_.GetNumCreatedSendStreams();
2279 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2280
2281 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2282 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002283 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2284 constexpr int kMinOverheadBps =
2285 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002286
2287 constexpr int kOpusMinBitrateBps = 6000;
2288 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002289 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002290 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002291 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002292 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002293
2294 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2295 parameters.options.audio_network_adaptor_config =
2296 rtc::Optional<std::string>("1234");
2297 SetSendParameters(parameters);
2298
ossu11bfc532017-02-16 05:37:06 -08002299 constexpr int kMinOverheadWithAnaBps =
2300 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002301
2302 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002303 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002304
minyuececec102017-03-27 13:04:25 -07002305 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002306 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002307}
2308
minyuececec102017-03-27 13:04:25 -07002309// This test is similar to
2310// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2311// additional field trial.
2312TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2313 SetRtpSendParameterUpdatesMaxBitrate) {
2314 EXPECT_TRUE(SetupSendStream());
2315 cricket::AudioSendParameters send_parameters;
2316 send_parameters.codecs.push_back(kOpusCodec);
2317 SetSendParameters(send_parameters);
2318
2319 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2320 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2321 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2322
2323 constexpr int kMaxBitrateBps = 6000;
2324 rtp_parameters.encodings[0].max_bitrate_bps =
2325 rtc::Optional<int>(kMaxBitrateBps);
2326 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2327
2328 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2329#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2330 constexpr int kMinOverhead = 3333;
2331#else
2332 constexpr int kMinOverhead = 6666;
2333#endif
2334 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2335}
2336
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002337// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002338// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002339TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002340 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002341 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002342}
2343
2344TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2345 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002346 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002347 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002348 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002349 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002350 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002351 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002352 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002353
solenberg85a04962015-10-27 03:35:21 -07002354 // Check stats for the added streams.
2355 {
2356 cricket::VoiceMediaInfo info;
2357 EXPECT_EQ(true, channel_->GetStats(&info));
2358
2359 // We have added one send stream. We should see the stats we've set.
2360 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002361 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002362 // We have added one receive stream. We should see empty stats.
2363 EXPECT_EQ(info.receivers.size(), 1u);
2364 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2365 }
solenberg1ac56142015-10-13 03:58:19 -07002366
solenberg566ef242015-11-06 15:34:49 -08002367 // Start sending - this affects some reported stats.
2368 {
2369 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002370 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002371 EXPECT_EQ(true, channel_->GetStats(&info));
2372 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002373 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002374 }
2375
solenberg2100c0b2017-03-01 11:29:29 -08002376 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002377 {
2378 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002379 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002380 EXPECT_EQ(true, channel_->GetStats(&info));
2381 EXPECT_EQ(1u, info.senders.size());
2382 EXPECT_EQ(0u, info.receivers.size());
2383 }
solenberg1ac56142015-10-13 03:58:19 -07002384
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002385 // Deliver a new packet - a default receive stream should be created and we
2386 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002387 {
2388 cricket::VoiceMediaInfo info;
2389 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2390 SetAudioReceiveStreamStats();
2391 EXPECT_EQ(true, channel_->GetStats(&info));
2392 EXPECT_EQ(1u, info.senders.size());
2393 EXPECT_EQ(1u, info.receivers.size());
2394 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002395 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002396 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397}
2398
2399// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002400// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002402 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002403 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2404 EXPECT_TRUE(AddRecvStream(kSsrcY));
2405 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002406}
2407
2408// Test that the local SSRC is the same on sending and receiving channels if the
2409// receive channel is created before the send channel.
2410TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002411 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002412 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002414 cricket::StreamParams::CreateLegacy(kSsrcX)));
2415 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2416 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417}
2418
2419// Test that we can properly receive packets.
2420TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002421 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002422 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002424
2425 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2426 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that we can properly receive packets on multiple streams.
2430TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002431 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002432 const uint32_t ssrc1 = 1;
2433 const uint32_t ssrc2 = 2;
2434 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002435 EXPECT_TRUE(AddRecvStream(ssrc1));
2436 EXPECT_TRUE(AddRecvStream(ssrc2));
2437 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002439 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002440 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002442 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443 }
mflodman3d7db262016-04-29 00:57:13 -07002444
2445 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2446 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2447 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2448
2449 EXPECT_EQ(s1.received_packets(), 0);
2450 EXPECT_EQ(s2.received_packets(), 0);
2451 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002452
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002454 EXPECT_EQ(s1.received_packets(), 0);
2455 EXPECT_EQ(s2.received_packets(), 0);
2456 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002457
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002458 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002459 EXPECT_EQ(s1.received_packets(), 1);
2460 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2461 EXPECT_EQ(s2.received_packets(), 0);
2462 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002463
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002465 EXPECT_EQ(s1.received_packets(), 1);
2466 EXPECT_EQ(s2.received_packets(), 1);
2467 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2468 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002469
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002471 EXPECT_EQ(s1.received_packets(), 1);
2472 EXPECT_EQ(s2.received_packets(), 1);
2473 EXPECT_EQ(s3.received_packets(), 1);
2474 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002475
mflodman3d7db262016-04-29 00:57:13 -07002476 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2477 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2478 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479}
2480
solenberg2100c0b2017-03-01 11:29:29 -08002481// Test that receiving on an unsignaled stream works (a stream is created).
2482TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002483 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002484 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2485
solenberg7e63ef02015-11-20 00:19:43 -08002486 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002487
2488 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002489 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2490 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002491}
2492
solenberg2100c0b2017-03-01 11:29:29 -08002493// Test that receiving N unsignaled stream works (streams will be created), and
2494// that packets are forwarded to them all.
2495TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002496 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002497 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002498 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2499
solenberg2100c0b2017-03-01 11:29:29 -08002500 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002501 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002502 rtc::SetBE32(&packet[8], ssrc);
2503 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002504
solenberg2100c0b2017-03-01 11:29:29 -08002505 // Verify we have one new stream for each loop iteration.
2506 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002507 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2508 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002509 }
mflodman3d7db262016-04-29 00:57:13 -07002510
solenberg2100c0b2017-03-01 11:29:29 -08002511 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002512 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002513 rtc::SetBE32(&packet[8], ssrc);
2514 DeliverPacket(packet, sizeof(packet));
2515
solenbergebb349d2017-03-13 05:46:15 -07002516 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002517 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2518 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2519 }
2520
2521 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2522 constexpr uint32_t kAnotherSsrc = 667;
2523 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002524 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002525
2526 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002527 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002528 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002529 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002530 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2531 EXPECT_EQ(2, streams[i]->received_packets());
2532 }
2533 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2534 EXPECT_EQ(1, streams[i]->received_packets());
2535 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002536 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002537}
2538
solenberg2100c0b2017-03-01 11:29:29 -08002539// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002540// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002541TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002542 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002543 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002544 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2545
2546 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002547 const uint32_t signaled_ssrc = 1;
2548 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002549 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002550 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002551 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2552 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002553 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002554
2555 // Note that the first unknown SSRC cannot be 0, because we only support
2556 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002557 const uint32_t unsignaled_ssrc = 7011;
2558 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002559 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002560 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2561 packet, sizeof(packet)));
2562 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2563
2564 DeliverPacket(packet, sizeof(packet));
2565 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2566
2567 rtc::SetBE32(&packet[8], signaled_ssrc);
2568 DeliverPacket(packet, sizeof(packet));
2569 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2570 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002571}
2572
solenberg4904fb62017-02-17 12:01:14 -08002573// Two tests to verify that adding a receive stream with the same SSRC as a
2574// previously added unsignaled stream will only recreate underlying stream
2575// objects if the stream parameters have changed.
2576TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2577 EXPECT_TRUE(SetupChannel());
2578
2579 // Spawn unsignaled stream with SSRC=1.
2580 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2581 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2582 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2583 sizeof(kPcmuFrame)));
2584
2585 // Verify that the underlying stream object in Call is not recreated when a
2586 // stream with SSRC=1 is added.
2587 const auto& streams = call_.GetAudioReceiveStreams();
2588 EXPECT_EQ(1, streams.size());
2589 int audio_receive_stream_id = streams.front()->id();
2590 EXPECT_TRUE(AddRecvStream(1));
2591 EXPECT_EQ(1, streams.size());
2592 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2593}
2594
2595TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2596 EXPECT_TRUE(SetupChannel());
2597
2598 // Spawn unsignaled stream with SSRC=1.
2599 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2600 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2601 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2602 sizeof(kPcmuFrame)));
2603
2604 // Verify that the underlying stream object in Call *is* recreated when a
2605 // stream with SSRC=1 is added, and which has changed stream parameters.
2606 const auto& streams = call_.GetAudioReceiveStreams();
2607 EXPECT_EQ(1, streams.size());
2608 int audio_receive_stream_id = streams.front()->id();
2609 cricket::StreamParams stream_params;
2610 stream_params.ssrcs.push_back(1);
2611 stream_params.sync_label = "sync_label";
2612 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2613 EXPECT_EQ(1, streams.size());
2614 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2615}
2616
solenberg0a617e22015-10-20 15:49:38 -07002617// Test that we properly handle failures to add a receive stream.
2618TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002619 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002620 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002621 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002622}
2623
solenberg0a617e22015-10-20 15:49:38 -07002624// Test that we properly handle failures to add a send stream.
2625TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002626 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002627 voe_.set_fail_create_channel(true);
2628 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2629}
2630
solenberg1ac56142015-10-13 03:58:19 -07002631// Test that AddRecvStream creates new stream.
2632TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002633 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002634 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002635 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002636 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002637}
2638
2639// Test that after adding a recv stream, we do not decode more codecs than
2640// those previously passed into SetRecvCodecs.
2641TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002642 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002643 cricket::AudioRecvParameters parameters;
2644 parameters.codecs.push_back(kIsacCodec);
2645 parameters.codecs.push_back(kPcmuCodec);
2646 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002647 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002648 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2649 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2650 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651}
2652
2653// Test that we properly clean up any streams that were added, even if
2654// not explicitly removed.
2655TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002656 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002657 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002658 EXPECT_TRUE(AddRecvStream(1));
2659 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002660 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2661 delete channel_;
2662 channel_ = NULL;
2663 EXPECT_EQ(0, voe_.GetNumChannels());
2664}
2665
wu@webrtc.org78187522013-10-07 23:32:02 +00002666TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002667 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002669}
2670
2671TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002672 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002673 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002674 // Manually delete channel to simulate a failure.
2675 int channel = voe_.GetLastChannel();
2676 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2677 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002678 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002679 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002680 EXPECT_NE(channel, new_channel);
2681 // The last created channel is deleted too.
2682 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002683}
2684
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002685// Test the InsertDtmf on default send stream as caller.
2686TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002687 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688}
2689
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002690// Test the InsertDtmf on default send stream as callee
2691TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002692 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002693}
2694
2695// Test the InsertDtmf on specified send stream as caller.
2696TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002697 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002698}
2699
2700// Test the InsertDtmf on specified send stream as callee.
2701TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002702 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703}
2704
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002706 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002707 EXPECT_CALL(adm_,
2708 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2709 EXPECT_CALL(adm_,
2710 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2711 EXPECT_CALL(adm_,
2712 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002713
solenberg246b8172015-12-08 09:50:23 -08002714 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2715 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716
solenberg246b8172015-12-08 09:50:23 -08002717 // Nothing set in AudioOptions, so everything should be as default.
2718 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002719 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002720 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002721 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2722 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002723
2724 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002725 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2726 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002727 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002728 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729
2730 // Turn echo cancellation back on, with settings, and make sure
2731 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002732 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2733 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002734 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002735 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002736
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002737 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2738 // control.
solenberg76377c52017-02-21 00:54:31 -08002739 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2740 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002741 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002742 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002743
2744 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002745 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2746 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002747 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2748 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2749 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002750 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002751
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002752 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002753 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002755 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002757
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002759 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002763 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002764 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765
2766 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002767 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2768 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2769 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002771 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2772 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774
2775 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002776 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2781 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2782 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002783 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2784 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2785 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2786 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002787 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002788 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002789
solenberg1ac56142015-10-13 03:58:19 -07002790 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002791 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2794 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2795 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2797 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002798 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799}
2800
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002802 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002803 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002804 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002805 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002806 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002807 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002808 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002809 EXPECT_CALL(adm_,
2810 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2811 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2812 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002813 webrtc::AudioProcessing::Config apm_config;
2814 EXPECT_CALL(*apm_, GetConfig())
2815 .Times(10)
2816 .WillRepeatedly(ReturnPointee(&apm_config));
2817 EXPECT_CALL(*apm_, ApplyConfig(_))
2818 .Times(10)
2819 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002820 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002821
kwiberg686a8ef2016-02-26 03:00:35 -08002822 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002823 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002824 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002825 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002826 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002827 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002828
2829 // Have to add a stream to make SetSend work.
2830 cricket::StreamParams stream1;
2831 stream1.ssrcs.push_back(1);
2832 channel1->AddSendStream(stream1);
2833 cricket::StreamParams stream2;
2834 stream2.ssrcs.push_back(2);
2835 channel2->AddSendStream(stream2);
2836
2837 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002838 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002839 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2840 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2841 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002842 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2843 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2844 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2845 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2846 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002847 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002848 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002849 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002850 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002851
2852 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002853 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002854 parameters_options_no_ns.options.noise_suppression =
2855 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002856 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2857 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2858 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2859 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002861 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002862 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002863 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2864 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2865 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002866 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867
2868 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002869 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002870 parameters_options_no_agc.options.auto_gain_control =
2871 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002872 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2873 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002877 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002878 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2879 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2880 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002881 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002888 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002895 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2898 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2899 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002903
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002904 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002905 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2906 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002907 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002908 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002909 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002910 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002916 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002917 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2918 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2919 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002920 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921}
2922
wu@webrtc.orgde305012013-10-31 15:40:38 +00002923// This test verifies DSCP settings are properly applied on voice media channel.
2924TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002925 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002926 cricket::FakeNetworkInterface network_interface;
2927 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002928 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002929
peahb1c9d1d2017-07-25 15:45:24 -07002930 webrtc::AudioProcessing::Config apm_config;
2931 EXPECT_CALL(*apm_, GetConfig())
2932 .Times(3)
2933 .WillRepeatedly(ReturnPointee(&apm_config));
2934 EXPECT_CALL(*apm_, ApplyConfig(_))
2935 .Times(3)
2936 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002937 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002938
solenbergbc37fc82016-04-04 09:54:44 -07002939 channel.reset(
2940 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002941 channel->SetInterface(&network_interface);
2942 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2943 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2944
2945 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002946 channel.reset(
2947 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002948 channel->SetInterface(&network_interface);
2949 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2950
2951 // Verify that setting the option to false resets the
2952 // DiffServCodePoint.
2953 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002954 channel.reset(
2955 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002956 channel->SetInterface(&network_interface);
2957 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2958 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2959
2960 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002961}
2962
solenberg1ac56142015-10-13 03:58:19 -07002963TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002964 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002965 cricket::WebRtcVoiceMediaChannel* media_channel =
2966 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002967 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002968 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002969 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002970 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2971 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2972 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002973 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002974 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975}
2976
solenberg1ac56142015-10-13 03:58:19 -07002977TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002978 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002980 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2981 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2982 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002983 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002984 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002985 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2986 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002987 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002988 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002989 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002990 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991}
2992
solenberg4bac9c52015-10-09 02:32:53 -07002993TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002994 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002995 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002997 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002999 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3000 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3001 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003002}
3003
solenberg2100c0b2017-03-01 11:29:29 -08003004TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003005 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003006
3007 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003008 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003009 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3010
3011 // Should remember the volume "2" which will be set on new unsignaled streams,
3012 // and also set the gain to 2 on existing unsignaled streams.
3013 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3014 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3015
3016 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3017 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3018 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3019 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3020 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3021 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3022
3023 // Setting gain with SSRC=0 should affect all unsignaled streams.
3024 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003025 if (kMaxUnsignaledRecvStreams > 1) {
3026 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3027 }
solenberg2100c0b2017-03-01 11:29:29 -08003028 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3029
3030 // Setting gain on an individual stream affects only that.
3031 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003032 if (kMaxUnsignaledRecvStreams > 1) {
3033 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3034 }
solenberg2100c0b2017-03-01 11:29:29 -08003035 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003036}
3037
pbos8fc7fa72015-07-15 08:02:58 -07003038TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003039 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003040 const std::string kSyncLabel = "AvSyncLabel";
3041
solenbergff976312016-03-30 23:28:51 -07003042 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003043 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3044 sp.sync_label = kSyncLabel;
3045 // Creating two channels to make sure that sync label is set properly for both
3046 // the default voice channel and following ones.
3047 EXPECT_TRUE(channel_->AddRecvStream(sp));
3048 sp.ssrcs[0] += 1;
3049 EXPECT_TRUE(channel_->AddRecvStream(sp));
3050
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003051 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003052 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003053 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003054 << "SyncGroup should be set based on sync_label";
3055 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003056 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003057 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003058}
3059
solenberg3a941542015-11-16 07:34:50 -08003060// TODO(solenberg): Remove, once recv streams are configured through Call.
3061// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003062TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003063 // Test that setting the header extensions results in the expected state
3064 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003065 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003066 ssrcs.push_back(223);
3067 ssrcs.push_back(224);
3068
solenbergff976312016-03-30 23:28:51 -07003069 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003070 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003071 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003072 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003073 cricket::StreamParams::CreateLegacy(ssrc)));
3074 }
3075
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003076 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003077 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003078 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003079 EXPECT_NE(nullptr, s);
3080 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3081 }
3082
3083 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003084 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003085 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003086 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003087 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003088 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003089 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003090 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 EXPECT_NE(nullptr, s);
3092 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003093 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3094 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 for (const auto& s_ext : s_exts) {
3096 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003097 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 }
3099 }
3100 }
3101 }
3102
3103 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003104 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003105 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003106 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107 EXPECT_NE(nullptr, s);
3108 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3109 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003110}
3111
3112TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3113 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003114 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003115 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003116 static const unsigned char kRtcp[] = {
3117 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3118 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3121 };
jbaucheec21bd2016-03-20 06:15:43 -07003122 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123
solenbergff976312016-03-30 23:28:51 -07003124 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 cricket::WebRtcVoiceMediaChannel* media_channel =
3126 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003127 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 EXPECT_TRUE(media_channel->AddRecvStream(
3129 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3130
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003131 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003132 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003133 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134 EXPECT_EQ(0, s->received_packets());
3135 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3136 EXPECT_EQ(1, s->received_packets());
3137 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3138 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139}
Minyue2013aec2015-05-13 14:14:42 +02003140
solenberg0a617e22015-10-20 15:49:38 -07003141// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003142// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003143TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003144 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003145 EXPECT_TRUE(AddRecvStream(kSsrcY));
3146 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003147 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003148 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3149 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3150 EXPECT_TRUE(AddRecvStream(kSsrcW));
3151 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003152}
3153
solenberg7602aab2016-11-14 11:30:07 -08003154TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3155 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003156 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003157 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003158 cricket::StreamParams::CreateLegacy(kSsrcY)));
3159 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3160 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3161 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003162 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003163 cricket::StreamParams::CreateLegacy(kSsrcW)));
3164 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3165 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003166}
stefan658910c2015-09-03 05:48:32 -07003167
deadbeef884f5852016-01-15 09:20:04 -08003168TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003169 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003170 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3171 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003172
3173 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003174 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3175 EXPECT_TRUE(AddRecvStream(kSsrcX));
3176 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003177
3178 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003179 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3180 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003181
3182 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003183 channel_->SetRawAudioSink(kSsrcX, nullptr);
3184 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003185}
3186
solenberg2100c0b2017-03-01 11:29:29 -08003187TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003188 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003189 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3190 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003191 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3192 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003193
3194 // Should be able to set a default sink even when no stream exists.
3195 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3196
solenberg2100c0b2017-03-01 11:29:29 -08003197 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3198 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003199 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003200 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003201
3202 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003203 channel_->SetRawAudioSink(kSsrc0, nullptr);
3204 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003207 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3208 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003209
3210 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003212 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003213 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3214
3215 // Spawn another unsignaled stream - it should be assigned the default sink
3216 // and the previous unsignaled stream should lose it.
3217 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3218 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3219 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3220 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003221 if (kMaxUnsignaledRecvStreams > 1) {
3222 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3223 }
solenberg2100c0b2017-03-01 11:29:29 -08003224 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3225
3226 // Reset the default sink - the second unsignaled stream should lose it.
3227 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3230 }
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3232
3233 // Try setting the default sink while two streams exists.
3234 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3237 }
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3239
3240 // Try setting the sink for the first unsignaled stream using its known SSRC.
3241 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003242 if (kMaxUnsignaledRecvStreams > 1) {
3243 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3244 }
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003246 if (kMaxUnsignaledRecvStreams > 1) {
3247 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3248 }
deadbeef884f5852016-01-15 09:20:04 -08003249}
3250
skvlad7a43d252016-03-22 15:32:27 -07003251// Test that, just like the video channel, the voice channel communicates the
3252// network state to the call.
3253TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003254 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003255
3256 EXPECT_EQ(webrtc::kNetworkUp,
3257 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3258 EXPECT_EQ(webrtc::kNetworkUp,
3259 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3260
3261 channel_->OnReadyToSend(false);
3262 EXPECT_EQ(webrtc::kNetworkDown,
3263 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3264 EXPECT_EQ(webrtc::kNetworkUp,
3265 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3266
3267 channel_->OnReadyToSend(true);
3268 EXPECT_EQ(webrtc::kNetworkUp,
3269 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3270 EXPECT_EQ(webrtc::kNetworkUp,
3271 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3272}
3273
aleloi18e0b672016-10-04 02:45:47 -07003274// Test that playout is still started after changing parameters
3275TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3276 SetupRecvStream();
3277 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003279
3280 // Changing RTP header extensions will recreate the AudioReceiveStream.
3281 cricket::AudioRecvParameters parameters;
3282 parameters.extensions.push_back(
3283 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3284 channel_->SetRecvParameters(parameters);
3285
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003287}
3288
stefan658910c2015-09-03 05:48:32 -07003289// Tests that the library initializes and shuts down properly.
3290TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003291 // If the VoiceEngine wants to gather available codecs early, that's fine but
3292 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003293 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3294 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003295 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003296 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003297 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003298 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003299 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003300 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003301 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003302 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3303 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003304 EXPECT_TRUE(channel != nullptr);
3305 delete channel;
solenbergff976312016-03-30 23:28:51 -07003306}
stefan658910c2015-09-03 05:48:32 -07003307
solenbergff976312016-03-30 23:28:51 -07003308// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003309TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3310 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3311 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3312 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003313 // Return 100ms just in case this function gets called. If we don't,
3314 // we could enter a tight loop since the mock would return 0.
3315 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003316 {
peaha9cc40b2017-06-29 08:32:09 -07003317 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3318 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003319 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003320 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003321 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003322 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003323 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003324 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003325 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003326 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3327 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3328 EXPECT_TRUE(channel != nullptr);
3329 delete channel;
3330 }
stefan658910c2015-09-03 05:48:32 -07003331}
3332
ossu20a4b3f2017-04-27 02:08:52 -07003333// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3334TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003335 // TODO(ossu): Why are the payload types of codecs with non-static payload
3336 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003337 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3338 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003339 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003340 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003341 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003342 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003343 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003344 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3345 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3346 (clockrate == 0 || codec.clockrate == clockrate);
3347 };
3348 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003349 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003350 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003351 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003352 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003353 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003354 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003355 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003356 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003358 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003359 EXPECT_EQ(126, codec.id);
3360 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3361 // Remove these checks once both send and receive side assigns payload types
3362 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003363 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003364 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003365 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003366 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003367 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003368 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003369 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003370 EXPECT_EQ(111, codec.id);
3371 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3372 EXPECT_EQ("10", codec.params.find("minptime")->second);
3373 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3374 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003375 }
3376 }
stefan658910c2015-09-03 05:48:32 -07003377}
3378
3379// Tests that VoE supports at least 32 channels
3380TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003381 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3382 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003383 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003384 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003385 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003386 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003387 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003388 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003389 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003390
3391 cricket::VoiceMediaChannel* channels[32];
3392 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003393 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003394 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3395 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003396 if (!channel)
3397 break;
stefan658910c2015-09-03 05:48:32 -07003398 channels[num_channels++] = channel;
3399 }
3400
tfarina5237aaf2015-11-10 23:44:30 -08003401 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003402 EXPECT_EQ(expected, num_channels);
3403
3404 while (num_channels > 0) {
3405 delete channels[--num_channels];
3406 }
stefan658910c2015-09-03 05:48:32 -07003407}
3408
3409// Test that we set our preferred codecs properly.
3410TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003411 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3412 // - Check that our builtin codecs are usable by Channel.
3413 // - The codecs provided by the engine is usable by Channel.
3414 // It does not check that the codecs in the RecvParameters are actually
3415 // what we sent in - though it's probably reasonable to expect so, if
3416 // SetRecvParameters returns true.
3417 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003418 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3419 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003420 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003421 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003422 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003423 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003424 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003425 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003426 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003427 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3428 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003429 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003430 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003431 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003432}
ossu9def8002017-02-09 05:14:32 -08003433
3434TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3435 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003436 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3437 {48000, 2, 16000, 10000, 20000}};
3438 spec1.info.allow_comfort_noise = false;
3439 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003440 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003441 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3442 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003443 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003444 specs.push_back(webrtc::AudioCodecSpec{
3445 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3446 {16000, 1, 13300}});
3447 specs.push_back(
3448 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3449 specs.push_back(
3450 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003451
ossueb1fde42017-05-02 06:46:30 -07003452 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3453 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3454 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003455 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003456 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003457 .WillOnce(Return(specs));
3458
peaha9cc40b2017-06-29 08:32:09 -07003459 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3460 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003461 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003462 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003463 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003464 auto codecs = engine.recv_codecs();
3465 EXPECT_EQ(11, codecs.size());
3466
3467 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3468 // check the actual values safely, to provide better test results.
3469 auto get_codec =
3470 [&codecs](size_t index) -> const cricket::AudioCodec& {
3471 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3472 if (codecs.size() > index)
3473 return codecs[index];
3474 return missing_codec;
3475 };
3476
3477 // Ensure the general codecs are generated first and in order.
3478 for (size_t i = 0; i != specs.size(); ++i) {
3479 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3480 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3481 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3482 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3483 }
3484
3485 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003486 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003487 auto find_codec =
3488 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3489 for (size_t i = 0; i != codecs.size(); ++i) {
3490 const cricket::AudioCodec& codec = codecs[i];
3491 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3492 codec.clockrate == format.clockrate_hz &&
3493 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003494 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003495 }
3496 }
3497 return -1;
3498 };
3499
3500 // Ensure all supplementary codecs are generated last. Their internal ordering
3501 // is not important.
3502 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3503 const int num_specs = static_cast<int>(specs.size());
3504 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3505 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3506 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3507 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3508 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3509 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3510 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3511}