blob: 67fde12194077c05d95a600c9a82f40576cedcd7 [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;
ivoce1198e02017-09-08 08:13:19 -0700549 stats.ana_statistics.bitrate_action_counter = rtc::Optional<uint32_t>(321);
550 stats.ana_statistics.channel_action_counter = rtc::Optional<uint32_t>(432);
551 stats.ana_statistics.dtx_action_counter = rtc::Optional<uint32_t>(543);
552 stats.ana_statistics.fec_action_counter = rtc::Optional<uint32_t>(654);
553 stats.ana_statistics.frame_length_action_counter =
554 rtc::Optional<uint32_t>(765);
solenberg85a04962015-10-27 03:35:21 -0700555 stats.typing_noise_detected = true;
556 return stats;
557 }
558 void SetAudioSendStreamStats() {
559 for (auto* s : call_.GetAudioSendStreams()) {
560 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200561 }
solenberg85a04962015-10-27 03:35:21 -0700562 }
solenberg566ef242015-11-06 15:34:49 -0800563 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
564 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700565 const auto stats = GetAudioSendStreamStats();
566 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
567 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
568 EXPECT_EQ(info.packets_sent, stats.packets_sent);
569 EXPECT_EQ(info.packets_lost, stats.packets_lost);
570 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
571 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800572 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700573 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
574 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
575 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
576 EXPECT_EQ(info.audio_level, stats.audio_level);
577 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
578 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
579 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
580 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
581 EXPECT_EQ(info.echo_return_loss_enhancement,
582 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700583 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800584 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
585 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700586 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
587 stats.ana_statistics.bitrate_action_counter);
588 EXPECT_EQ(info.ana_statistics.channel_action_counter,
589 stats.ana_statistics.channel_action_counter);
590 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
591 stats.ana_statistics.dtx_action_counter);
592 EXPECT_EQ(info.ana_statistics.fec_action_counter,
593 stats.ana_statistics.fec_action_counter);
594 EXPECT_EQ(info.ana_statistics.frame_length_action_counter,
595 stats.ana_statistics.frame_length_action_counter);
solenberg566ef242015-11-06 15:34:49 -0800596 EXPECT_EQ(info.typing_noise_detected,
597 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700598 }
599
600 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
601 webrtc::AudioReceiveStream::Stats stats;
602 stats.remote_ssrc = 123;
603 stats.bytes_rcvd = 456;
604 stats.packets_rcvd = 768;
605 stats.packets_lost = 101;
606 stats.fraction_lost = 23.45f;
607 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800608 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700609 stats.ext_seqnum = 678;
610 stats.jitter_ms = 901;
611 stats.jitter_buffer_ms = 234;
612 stats.jitter_buffer_preferred_ms = 567;
613 stats.delay_estimate_ms = 890;
614 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700615 stats.total_samples_received = 5678901;
616 stats.concealed_samples = 234;
solenberg85a04962015-10-27 03:35:21 -0700617 stats.expand_rate = 5.67f;
618 stats.speech_expand_rate = 8.90f;
619 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200620 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700621 stats.accelerate_rate = 4.56f;
622 stats.preemptive_expand_rate = 7.89f;
623 stats.decoding_calls_to_silence_generator = 12;
624 stats.decoding_calls_to_neteq = 345;
625 stats.decoding_normal = 67890;
626 stats.decoding_plc = 1234;
627 stats.decoding_cng = 5678;
628 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700629 stats.decoding_muted_output = 3456;
630 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200631 return stats;
632 }
633 void SetAudioReceiveStreamStats() {
634 for (auto* s : call_.GetAudioReceiveStreams()) {
635 s->SetStats(GetAudioReceiveStreamStats());
636 }
637 }
638 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700639 const auto stats = GetAudioReceiveStreamStats();
640 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
641 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
642 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
643 EXPECT_EQ(info.packets_lost, stats.packets_lost);
644 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
645 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800646 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
648 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
649 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200650 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700651 stats.jitter_buffer_preferred_ms);
652 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
653 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700654 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
655 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
solenberg85a04962015-10-27 03:35:21 -0700656 EXPECT_EQ(info.expand_rate, stats.expand_rate);
657 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
658 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200659 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700660 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
661 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200662 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700663 stats.decoding_calls_to_silence_generator);
664 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
665 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
666 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
667 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
668 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700669 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700670 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200671 }
hbos1acfbd22016-11-17 23:43:29 -0800672 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
673 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
674 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
675 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
676 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
677 codec.ToCodecParameters());
678 }
679 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
680 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
681 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
682 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
683 codec.ToCodecParameters());
684 }
685 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200686
peah8271d042016-11-22 07:24:52 -0800687 bool IsHighPassFilterEnabled() {
688 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
689 }
690
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700692 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700693 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800694 webrtc::test::MockGainControl& apm_gc_;
695 webrtc::test::MockEchoCancellation& apm_ec_;
696 webrtc::test::MockNoiseSuppression& apm_ns_;
697 webrtc::test::MockVoiceDetection& apm_vd_;
698 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700699 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200700 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700702 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700703 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200704 cricket::AudioSendParameters send_parameters_;
705 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800706 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700707 webrtc::AudioProcessing::Config apm_config_;
708
stefanba4c0e42016-02-04 04:12:24 -0800709 private:
710 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711};
712
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000713// Tests that we can create and destroy a channel.
714TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700715 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716}
717
solenberg31fec402016-05-06 02:13:12 -0700718// Test that we can add a send stream and that it has the correct defaults.
719TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
720 EXPECT_TRUE(SetupChannel());
721 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800722 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
723 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
724 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700725 EXPECT_EQ("", config.rtp.c_name);
726 EXPECT_EQ(0u, config.rtp.extensions.size());
727 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
728 config.send_transport);
729}
730
731// Test that we can add a receive stream and that it has the correct defaults.
732TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
733 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800734 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700735 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800736 GetRecvStreamConfig(kSsrcX);
737 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700738 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
739 EXPECT_FALSE(config.rtp.transport_cc);
740 EXPECT_EQ(0u, config.rtp.extensions.size());
741 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
742 config.rtcp_send_transport);
743 EXPECT_EQ("", config.sync_group);
744}
745
stefanba4c0e42016-02-04 04:12:24 -0800746TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700747 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800748 bool opus_found = false;
749 for (cricket::AudioCodec codec : codecs) {
750 if (codec.name == "opus") {
751 EXPECT_TRUE(HasTransportCc(codec));
752 opus_found = true;
753 }
754 }
755 EXPECT_TRUE(opus_found);
756}
757
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758// Test that we set our inbound codecs properly, including changing PT.
759TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700760 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200761 cricket::AudioRecvParameters parameters;
762 parameters.codecs.push_back(kIsacCodec);
763 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800764 parameters.codecs.push_back(kTelephoneEventCodec1);
765 parameters.codecs.push_back(kTelephoneEventCodec2);
766 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200767 parameters.codecs[2].id = 126;
768 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800769 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700770 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
771 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
772 {{0, {"PCMU", 8000, 1}},
773 {106, {"ISAC", 16000, 1}},
774 {126, {"telephone-event", 8000, 1}},
775 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776}
777
778// Test that we fail to set an unknown inbound codec.
779TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700780 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200781 cricket::AudioRecvParameters parameters;
782 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700783 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200784 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
787// Test that we fail if we have duplicate types in the inbound list.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200790 cricket::AudioRecvParameters parameters;
791 parameters.codecs.push_back(kIsacCodec);
792 parameters.codecs.push_back(kCn16000Codec);
793 parameters.codecs[1].id = kIsacCodec.id;
794 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
797// Test that we can decode OPUS without stereo parameters.
798TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700799 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200800 cricket::AudioRecvParameters parameters;
801 parameters.codecs.push_back(kIsacCodec);
802 parameters.codecs.push_back(kPcmuCodec);
803 parameters.codecs.push_back(kOpusCodec);
804 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800805 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700806 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
807 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
808 {{0, {"PCMU", 8000, 1}},
809 {103, {"ISAC", 16000, 1}},
810 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811}
812
813// Test that we can decode OPUS with stereo = 0.
814TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700815 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200816 cricket::AudioRecvParameters parameters;
817 parameters.codecs.push_back(kIsacCodec);
818 parameters.codecs.push_back(kPcmuCodec);
819 parameters.codecs.push_back(kOpusCodec);
820 parameters.codecs[2].params["stereo"] = "0";
821 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800822 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700823 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
824 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
825 {{0, {"PCMU", 8000, 1}},
826 {103, {"ISAC", 16000, 1}},
827 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828}
829
830// Test that we can decode OPUS with stereo = 1.
831TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700832 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200833 cricket::AudioRecvParameters parameters;
834 parameters.codecs.push_back(kIsacCodec);
835 parameters.codecs.push_back(kPcmuCodec);
836 parameters.codecs.push_back(kOpusCodec);
837 parameters.codecs[2].params["stereo"] = "1";
838 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800839 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700840 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
841 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
842 {{0, {"PCMU", 8000, 1}},
843 {103, {"ISAC", 16000, 1}},
844 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845}
846
847// Test that changes to recv codecs are applied to all streams.
848TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700849 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200850 cricket::AudioRecvParameters parameters;
851 parameters.codecs.push_back(kIsacCodec);
852 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800853 parameters.codecs.push_back(kTelephoneEventCodec1);
854 parameters.codecs.push_back(kTelephoneEventCodec2);
855 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200856 parameters.codecs[2].id = 126;
857 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700858 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
859 EXPECT_TRUE(AddRecvStream(ssrc));
860 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
861 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
862 {{0, {"PCMU", 8000, 1}},
863 {106, {"ISAC", 16000, 1}},
864 {126, {"telephone-event", 8000, 1}},
865 {107, {"telephone-event", 32000, 1}}})));
866 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867}
868
869TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700870 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 cricket::AudioRecvParameters parameters;
872 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800873 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200874 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875
solenberg2100c0b2017-03-01 11:29:29 -0800876 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800877 ASSERT_EQ(1, dm.count(106));
878 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000879}
880
881// Test that we can apply the same set of codecs again while playing.
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
886 parameters.codecs.push_back(kCn16000Codec);
887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700888 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
deadbeefcb383672017-04-26 16:28:42 -0700891 // Remapping a payload type to a different codec should fail.
892 parameters.codecs[0] = kOpusCodec;
893 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800895 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
898// Test that we can add a codec while playing.
899TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700900 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200901 cricket::AudioRecvParameters parameters;
902 parameters.codecs.push_back(kIsacCodec);
903 parameters.codecs.push_back(kCn16000Codec);
904 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700905 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 parameters.codecs.push_back(kOpusCodec);
908 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800909 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910}
911
deadbeefcb383672017-04-26 16:28:42 -0700912// Test that we accept adding the same codec with a different payload type.
913// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
914TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
915 EXPECT_TRUE(SetupRecvStream());
916 cricket::AudioRecvParameters parameters;
917 parameters.codecs.push_back(kIsacCodec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
919
920 ++parameters.codecs[0].id;
921 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
922}
923
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700925 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000927 // Test that when autobw is enabled, bitrate is kept as the default
928 // value. autobw is enabled for the following tests because the target
929 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930
931 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700932 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
934 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700935 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
ossu20a4b3f2017-04-27 02:08:52 -0700937 // opus, default bitrate == 32000 in mono.
938 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939}
940
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000941TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700942 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
946 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700947 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700950 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
951 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
952 // Rates above the max (510000) should be capped.
953 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954}
955
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000956TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700957 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000958
959 // Test that we can only set a maximum bitrate for a fixed-rate codec
960 // if it's bigger than the fixed rate.
961
962 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
964 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
965 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
966 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
967 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
968 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
969 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000970}
971
972TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700973 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200974 const int kDesiredBitrate = 128000;
975 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700976 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200977 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700978 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000979
980 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800981 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000982
solenberg2100c0b2017-03-01 11:29:29 -0800983 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000984}
985
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986// Test that bitrate cannot be set for CBR codecs.
987// Bitrate is ignored if it is higher than the fixed bitrate.
988// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000989TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700990 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991
992 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700993 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800994 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200995
996 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700997 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800998 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200999
1000 send_parameters_.max_bandwidth_bps = 128;
1001 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001002 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003}
1004
skvlade0d46372016-04-07 22:59:22 -07001005// Test that the per-stream bitrate limit and the global
1006// bitrate limit both apply.
1007TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1008 EXPECT_TRUE(SetupSendStream());
1009
ossu20a4b3f2017-04-27 02:08:52 -07001010 // opus, default bitrate == 32000.
1011 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001012 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1013 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1014 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1015
1016 // CBR codecs allow both maximums to exceed the bitrate.
1017 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1018 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1019 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1020 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1021
1022 // CBR codecs don't allow per stream maximums to be too low.
1023 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1024 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1025}
1026
1027// Test that an attempt to set RtpParameters for a stream that does not exist
1028// fails.
1029TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1030 EXPECT_TRUE(SetupChannel());
1031 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001032 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001033 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1034
1035 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001036 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001037}
1038
1039TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001040 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001041 // This test verifies that setting RtpParameters succeeds only if
1042 // the structure contains exactly one encoding.
1043 // TODO(skvlad): Update this test when we start supporting setting parameters
1044 // for each encoding individually.
1045
1046 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001047 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001048 // Two or more encodings should result in failure.
1049 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001050 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001051 // Zero encodings should also fail.
1052 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001053 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001054}
1055
1056// Changing the SSRC through RtpParameters is not allowed.
1057TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1058 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001059 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001060 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001061 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001062}
1063
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001064// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001065// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001066TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1067 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001068 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001069 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001070 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001071 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001072 ASSERT_EQ(1u, parameters.encodings.size());
1073 ASSERT_TRUE(parameters.encodings[0].active);
1074 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001075 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1076 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001077
1078 // Now change it back to active and verify we resume sending.
1079 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001080 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1081 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082}
1083
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001084// Test that SetRtpSendParameters configures the correct encoding channel for
1085// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001086TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1087 SetupForMultiSendStream();
1088 // Create send streams.
1089 for (uint32_t ssrc : kSsrcs4) {
1090 EXPECT_TRUE(
1091 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1092 }
1093 // Configure one stream to be limited by the stream config, another to be
1094 // limited by the global max, and the third one with no per-stream limit
1095 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001096 SetGlobalMaxBitrate(kOpusCodec, 32000);
1097 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1098 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001099 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1100
ossu20a4b3f2017-04-27 02:08:52 -07001101 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1102 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1103 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001104
1105 // Remove the global cap; the streams should switch to their respective
1106 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001107 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001108 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1109 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1110 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001111}
1112
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001113// Test that GetRtpSendParameters returns the currently configured codecs.
1114TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001115 EXPECT_TRUE(SetupSendStream());
1116 cricket::AudioSendParameters parameters;
1117 parameters.codecs.push_back(kIsacCodec);
1118 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001119 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001120
solenberg2100c0b2017-03-01 11:29:29 -08001121 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001122 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001123 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1124 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001125}
1126
deadbeefcb443432016-12-12 11:12:36 -08001127// Test that GetRtpSendParameters returns an SSRC.
1128TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1129 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001130 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001131 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001132 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001133}
1134
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001136TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137 EXPECT_TRUE(SetupSendStream());
1138 cricket::AudioSendParameters parameters;
1139 parameters.codecs.push_back(kIsacCodec);
1140 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001141 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001142
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001144
1145 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001146 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001148 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001149 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1150 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151}
1152
minyuececec102017-03-27 13:04:25 -07001153// Test that max_bitrate_bps in send stream config gets updated correctly when
1154// SetRtpSendParameters is called.
1155TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1156 webrtc::test::ScopedFieldTrials override_field_trials(
1157 "WebRTC-Audio-SendSideBwe/Enabled/");
1158 EXPECT_TRUE(SetupSendStream());
1159 cricket::AudioSendParameters send_parameters;
1160 send_parameters.codecs.push_back(kOpusCodec);
1161 SetSendParameters(send_parameters);
1162
1163 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1164 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1165 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1166
1167 constexpr int kMaxBitrateBps = 6000;
1168 rtp_parameters.encodings[0].max_bitrate_bps =
1169 rtc::Optional<int>(kMaxBitrateBps);
1170 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1171
1172 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1173 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1174}
1175
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001176// Test that GetRtpReceiveParameters returns the currently configured codecs.
1177TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1178 EXPECT_TRUE(SetupRecvStream());
1179 cricket::AudioRecvParameters parameters;
1180 parameters.codecs.push_back(kIsacCodec);
1181 parameters.codecs.push_back(kPcmuCodec);
1182 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1183
1184 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001185 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001186 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1187 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1188 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1189}
1190
deadbeefcb443432016-12-12 11:12:36 -08001191// Test that GetRtpReceiveParameters returns an SSRC.
1192TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1193 EXPECT_TRUE(SetupRecvStream());
1194 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001195 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001196 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001197 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001198}
1199
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001200// Test that if we set/get parameters multiple times, we get the same results.
1201TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1202 EXPECT_TRUE(SetupRecvStream());
1203 cricket::AudioRecvParameters parameters;
1204 parameters.codecs.push_back(kIsacCodec);
1205 parameters.codecs.push_back(kPcmuCodec);
1206 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1207
1208 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001209 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210
1211 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001212 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213
1214 // ... And this shouldn't change the params returned by
1215 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001216 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1217 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001218}
1219
deadbeef3bc15102017-04-20 19:25:07 -07001220// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1221// aren't signaled. It should return an empty "RtpEncodingParameters" when
1222// configured to receive an unsignaled stream and no packets have been received
1223// yet, and start returning the SSRC once a packet has been received.
1224TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1225 ASSERT_TRUE(SetupChannel());
1226 // Call necessary methods to configure receiving a default stream as
1227 // soon as it arrives.
1228 cricket::AudioRecvParameters parameters;
1229 parameters.codecs.push_back(kIsacCodec);
1230 parameters.codecs.push_back(kPcmuCodec);
1231 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1232
1233 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1234 // stream. Should return nothing.
1235 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1236
1237 // Set a sink for an unsignaled stream.
1238 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1239 // Value of "0" means "unsignaled stream".
1240 channel_->SetRawAudioSink(0, std::move(fake_sink));
1241
1242 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1243 // in this method means "unsignaled stream".
1244 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1245 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1246 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1247
1248 // Receive PCMU packet (SSRC=1).
1249 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1250
1251 // The |ssrc| member should still be unset.
1252 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1253 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1254 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1255}
1256
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001257// Test that we apply codecs properly.
1258TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001259 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001260 cricket::AudioSendParameters parameters;
1261 parameters.codecs.push_back(kIsacCodec);
1262 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001263 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001264 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001265 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001266 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001267 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1268 EXPECT_EQ(96, send_codec_spec.payload_type);
1269 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1270 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1271 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1272 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001273 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001274}
1275
ossu20a4b3f2017-04-27 02:08:52 -07001276// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1277// AudioSendStream.
1278TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001279 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001280 cricket::AudioSendParameters parameters;
1281 parameters.codecs.push_back(kIsacCodec);
1282 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001283 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001284 parameters.codecs[0].id = 96;
1285 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001286 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001287 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001288 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001289 // Calling SetSendCodec again with same codec which is already set.
1290 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001291 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001292 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001293}
1294
ossu20a4b3f2017-04-27 02:08:52 -07001295// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1296// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001297
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001298// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001299TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001300 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001301 cricket::AudioSendParameters parameters;
1302 parameters.codecs.push_back(kOpusCodec);
1303 parameters.codecs[0].bitrate = 0;
1304 parameters.codecs[0].clockrate = 50000;
1305 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001306}
1307
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001308// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001309TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001310 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 cricket::AudioSendParameters parameters;
1312 parameters.codecs.push_back(kOpusCodec);
1313 parameters.codecs[0].bitrate = 0;
1314 parameters.codecs[0].channels = 0;
1315 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316}
1317
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001318// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001320 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001321 cricket::AudioSendParameters parameters;
1322 parameters.codecs.push_back(kOpusCodec);
1323 parameters.codecs[0].bitrate = 0;
1324 parameters.codecs[0].channels = 0;
1325 parameters.codecs[0].params["stereo"] = "1";
1326 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327}
1328
1329// Test that if channel is 1 for opus and there's no stereo, we fail.
1330TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001331 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001332 cricket::AudioSendParameters parameters;
1333 parameters.codecs.push_back(kOpusCodec);
1334 parameters.codecs[0].bitrate = 0;
1335 parameters.codecs[0].channels = 1;
1336 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337}
1338
1339// Test that if channel is 1 for opus and stereo=0, we fail.
1340TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001341 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 cricket::AudioSendParameters parameters;
1343 parameters.codecs.push_back(kOpusCodec);
1344 parameters.codecs[0].bitrate = 0;
1345 parameters.codecs[0].channels = 1;
1346 parameters.codecs[0].params["stereo"] = "0";
1347 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348}
1349
1350// Test that if channel is 1 for opus and stereo=1, we fail.
1351TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001352 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001353 cricket::AudioSendParameters parameters;
1354 parameters.codecs.push_back(kOpusCodec);
1355 parameters.codecs[0].bitrate = 0;
1356 parameters.codecs[0].channels = 1;
1357 parameters.codecs[0].params["stereo"] = "1";
1358 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001359}
1360
ossu20a4b3f2017-04-27 02:08:52 -07001361// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001363 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001364 cricket::AudioSendParameters parameters;
1365 parameters.codecs.push_back(kOpusCodec);
1366 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001367 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001368 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001369}
1370
ossu20a4b3f2017-04-27 02:08:52 -07001371// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].bitrate = 0;
1377 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001378 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001379 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001380}
1381
ossu20a4b3f2017-04-27 02:08:52 -07001382// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001383TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001384 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001385 cricket::AudioSendParameters parameters;
1386 parameters.codecs.push_back(kOpusCodec);
1387 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001388 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001390 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001391 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001392
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001393 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001394 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001395 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001396}
1397
ossu20a4b3f2017-04-27 02:08:52 -07001398// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001399TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001400 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 cricket::AudioSendParameters parameters;
1402 parameters.codecs.push_back(kOpusCodec);
1403 parameters.codecs[0].bitrate = 0;
1404 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407}
1408
ossu20a4b3f2017-04-27 02:08:52 -07001409// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001415 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001418 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001419
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423}
1424
ossu20a4b3f2017-04-27 02:08:52 -07001425// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1433 EXPECT_EQ(111, spec.payload_type);
1434 EXPECT_EQ(96000, spec.target_bitrate_bps);
1435 EXPECT_EQ("opus", spec.format.name);
1436 EXPECT_EQ(2, spec.format.num_channels);
1437 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438}
1439
ossu20a4b3f2017-04-27 02:08:52 -07001440// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001442 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 cricket::AudioSendParameters parameters;
1444 parameters.codecs.push_back(kOpusCodec);
1445 parameters.codecs[0].bitrate = 30000;
1446 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001447 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001448 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449}
1450
ossu20a4b3f2017-04-27 02:08:52 -07001451// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001453 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 cricket::AudioSendParameters parameters;
1455 parameters.codecs.push_back(kOpusCodec);
1456 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001457 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001458 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459}
1460
ossu20a4b3f2017-04-27 02:08:52 -07001461// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001463 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001464 cricket::AudioSendParameters parameters;
1465 parameters.codecs.push_back(kOpusCodec);
1466 parameters.codecs[0].bitrate = 30000;
1467 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001468 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001469 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001470}
1471
stefan13f1a0a2016-11-30 07:22:58 -08001472TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1473 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1474 200000);
1475}
1476
1477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1478 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1479}
1480
1481TEST_F(WebRtcVoiceEngineTestFake,
1482 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1483 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1484}
1485
1486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1487 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1488}
1489
1490TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001491 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001492 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1493 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001494 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001495 SetSendParameters(send_parameters_);
1496 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1497 << "Setting max bitrate should keep previous min bitrate.";
1498 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1499 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001500 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001501}
1502
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001503// Test that we can enable NACK with opus as caller.
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001505 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001506 cricket::AudioSendParameters parameters;
1507 parameters.codecs.push_back(kOpusCodec);
1508 parameters.codecs[0].AddFeedbackParam(
1509 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1510 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001511 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001512 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001513 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514}
1515
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001516// Test that we can enable NACK with opus as callee.
1517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].AddFeedbackParam(
1522 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1523 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001524 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001526 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001528
1529 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001530 cricket::StreamParams::CreateLegacy(kSsrcX)));
1531 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001532}
1533
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001534// Test that we can enable NACK on receive streams.
1535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001538 cricket::AudioSendParameters parameters;
1539 parameters.codecs.push_back(kOpusCodec);
1540 parameters.codecs[0].AddFeedbackParam(
1541 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1542 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001543 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1544 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001546 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1547 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548}
1549
1550// Test that we can disable NACK.
1551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001552 EXPECT_TRUE(SetupSendStream());
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);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001561 parameters.codecs.clear();
1562 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565}
1566
1567// Test that we can disable NACK on receive streams.
1568TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001569 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001570 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 cricket::AudioSendParameters parameters;
1572 parameters.codecs.push_back(kOpusCodec);
1573 parameters.codecs[0].AddFeedbackParam(
1574 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1575 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1578 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 parameters.codecs.clear();
1581 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001582 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001583 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1584 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585}
1586
1587// Test that NACK is enabled on a new receive stream.
1588TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001589 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001590 cricket::AudioSendParameters parameters;
1591 parameters.codecs.push_back(kIsacCodec);
1592 parameters.codecs.push_back(kCn16000Codec);
1593 parameters.codecs[0].AddFeedbackParam(
1594 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1595 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598
solenberg2100c0b2017-03-01 11:29:29 -08001599 EXPECT_TRUE(AddRecvStream(kSsrcY));
1600 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1601 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1602 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603}
1604
stefanba4c0e42016-02-04 04:12:24 -08001605TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001606 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001607 cricket::AudioSendParameters send_parameters;
1608 send_parameters.codecs.push_back(kOpusCodec);
1609 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001611
1612 cricket::AudioRecvParameters recv_parameters;
1613 recv_parameters.codecs.push_back(kIsacCodec);
1614 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_TRUE(AddRecvStream(kSsrcX));
1616 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001617 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001618 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001619
ossudedfd282016-06-14 07:12:39 -07001620 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001622 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001623 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001624 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001625}
1626
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001627// Test that we can switch back and forth between Opus and ISAC with CN.
1628TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001629 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001630
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001631 cricket::AudioSendParameters opus_parameters;
1632 opus_parameters.codecs.push_back(kOpusCodec);
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
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001640 cricket::AudioSendParameters isac_parameters;
1641 isac_parameters.codecs.push_back(kIsacCodec);
1642 isac_parameters.codecs.push_back(kCn16000Codec);
1643 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001644 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001645 {
ossu20a4b3f2017-04-27 02:08:52 -07001646 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1647 EXPECT_EQ(103, spec.payload_type);
1648 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001649 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001650
solenberg059fb442016-10-26 05:12:24 -07001651 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001652 {
ossu20a4b3f2017-04-27 02:08:52 -07001653 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1654 EXPECT_EQ(111, spec.payload_type);
1655 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001656 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001657}
1658
1659// Test that we handle various ways of specifying bitrate.
1660TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001661 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001662 cricket::AudioSendParameters parameters;
1663 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001665 {
ossu20a4b3f2017-04-27 02:08:52 -07001666 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1667 EXPECT_EQ(103, spec.payload_type);
1668 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1669 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001670 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001674 {
ossu20a4b3f2017-04-27 02:08:52 -07001675 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1676 EXPECT_EQ(103, spec.payload_type);
1677 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1678 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001679 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
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(103, spec.payload_type);
1685 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1686 EXPECT_EQ(28000, 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] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001690 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001691 {
ossu20a4b3f2017-04-27 02:08:52 -07001692 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1693 EXPECT_EQ(0, spec.payload_type);
1694 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1695 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001696 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001698 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001699 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001700 {
ossu20a4b3f2017-04-27 02:08:52 -07001701 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1702 EXPECT_EQ(0, spec.payload_type);
1703 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1704 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001705 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001706
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001707 parameters.codecs[0] = kOpusCodec;
1708 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001710 {
ossu20a4b3f2017-04-27 02:08:52 -07001711 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1712 EXPECT_EQ(111, spec.payload_type);
1713 EXPECT_STREQ("opus", spec.format.name.c_str());
1714 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001715 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716}
1717
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001718// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001720 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001721 cricket::AudioSendParameters parameters;
1722 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001723}
1724
1725// Test that we can set send codecs even with telephone-event codec as the first
1726// one on the list.
1727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001728 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001729 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001730 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001731 parameters.codecs.push_back(kIsacCodec);
1732 parameters.codecs.push_back(kPcmuCodec);
1733 parameters.codecs[0].id = 98; // DTMF
1734 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001735 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001736 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1737 EXPECT_EQ(96, spec.payload_type);
1738 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001739 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001740}
1741
solenberg31642aa2016-03-14 08:00:37 -07001742// Test that payload type range is limited for telephone-event codec.
1743TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001744 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001745 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001746 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001747 parameters.codecs.push_back(kIsacCodec);
1748 parameters.codecs[0].id = 0; // DTMF
1749 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001751 EXPECT_TRUE(channel_->CanInsertDtmf());
1752 parameters.codecs[0].id = 128; // DTMF
1753 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1754 EXPECT_FALSE(channel_->CanInsertDtmf());
1755 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001756 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001757 EXPECT_TRUE(channel_->CanInsertDtmf());
1758 parameters.codecs[0].id = -1; // DTMF
1759 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1760 EXPECT_FALSE(channel_->CanInsertDtmf());
1761}
1762
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001763// Test that we can set send codecs even with CN codec as the first
1764// one on the list.
1765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001766 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001767 cricket::AudioSendParameters parameters;
1768 parameters.codecs.push_back(kCn16000Codec);
1769 parameters.codecs.push_back(kIsacCodec);
1770 parameters.codecs.push_back(kPcmuCodec);
1771 parameters.codecs[0].id = 98; // wideband CN
1772 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001773 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001774 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1775 EXPECT_EQ(96, send_codec_spec.payload_type);
1776 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001777 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778}
1779
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001780// Test that we set VAD and DTMF types correctly as caller.
1781TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001782 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001783 cricket::AudioSendParameters parameters;
1784 parameters.codecs.push_back(kIsacCodec);
1785 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 parameters.codecs.push_back(kCn16000Codec);
1788 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001789 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001790 parameters.codecs[0].id = 96;
1791 parameters.codecs[2].id = 97; // wideband CN
1792 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001794 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1795 EXPECT_EQ(96, send_codec_spec.payload_type);
1796 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1797 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001798 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001799 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800}
1801
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001802// Test that we set VAD and DTMF types correctly as callee.
1803TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001804 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 cricket::AudioSendParameters parameters;
1806 parameters.codecs.push_back(kIsacCodec);
1807 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001808 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001809 parameters.codecs.push_back(kCn16000Codec);
1810 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001811 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001812 parameters.codecs[0].id = 96;
1813 parameters.codecs[2].id = 97; // wideband CN
1814 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001815 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001816 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001817 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001818
ossu20a4b3f2017-04-27 02:08:52 -07001819 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1820 EXPECT_EQ(96, send_codec_spec.payload_type);
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);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001824 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001825}
1826
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001827// Test that we only apply VAD if we have a CN codec that matches the
1828// send codec clockrate.
1829TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001830 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001831 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001832 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 parameters.codecs.push_back(kIsacCodec);
1834 parameters.codecs.push_back(kCn16000Codec);
1835 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001837 {
ossu20a4b3f2017-04-27 02:08:52 -07001838 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1839 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1840 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001841 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001842 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001843 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001845 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001846 {
ossu20a4b3f2017-04-27 02:08:52 -07001847 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1848 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1849 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001850 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001851 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001852 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001854 {
ossu20a4b3f2017-04-27 02:08:52 -07001855 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1856 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1857 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001858 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001859 }
Brave Yao5225dd82015-03-26 07:39:19 +08001860 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001861 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001863 {
ossu20a4b3f2017-04-27 02:08:52 -07001864 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1865 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1866 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001867 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001868}
1869
1870// Test that we perform case-insensitive matching of codec names.
1871TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001872 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001873 cricket::AudioSendParameters parameters;
1874 parameters.codecs.push_back(kIsacCodec);
1875 parameters.codecs.push_back(kPcmuCodec);
1876 parameters.codecs.push_back(kCn16000Codec);
1877 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001878 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001879 parameters.codecs[0].name = "iSaC";
1880 parameters.codecs[0].id = 96;
1881 parameters.codecs[2].id = 97; // wideband CN
1882 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001884 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1885 EXPECT_EQ(96, send_codec_spec.payload_type);
1886 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1887 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001888 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001889 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890}
1891
stefanba4c0e42016-02-04 04:12:24 -08001892class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1893 public:
1894 WebRtcVoiceEngineWithSendSideBweTest()
1895 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1896};
1897
1898TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1899 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001900 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001901 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001902 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1903 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1904 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001905 extension.id);
1906 return;
1907 }
1908 }
1909 FAIL() << "Transport sequence number extension not in header-extension list.";
1910}
1911
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001912// Test support for audio level header extension.
1913TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001914 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001915}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001916TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001917 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001918}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001919
solenbergd4adce42016-11-17 06:26:52 -08001920// Test support for transport sequence number header extension.
1921TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1922 TestSetSendRtpHeaderExtensions(
1923 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001924}
solenbergd4adce42016-11-17 06:26:52 -08001925TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1926 TestSetRecvRtpHeaderExtensions(
1927 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928}
1929
solenberg1ac56142015-10-13 03:58:19 -07001930// Test that we can create a channel and start sending on it.
1931TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001932 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001933 SetSendParameters(send_parameters_);
1934 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001935 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001936 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001937 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001938}
1939
1940// Test that a channel will send if and only if it has a source and is enabled
1941// for sending.
1942TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001943 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001944 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001945 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001946 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001947 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1948 SetAudioSend(kSsrcX, true, &fake_source_);
1949 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1950 SetAudioSend(kSsrcX, true, nullptr);
1951 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001952}
1953
solenberg94218532016-06-16 10:53:22 -07001954// Test that a channel is muted/unmuted.
1955TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1956 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001957 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001958 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1959 SetAudioSend(kSsrcX, true, nullptr);
1960 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1961 SetAudioSend(kSsrcX, false, nullptr);
1962 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001963}
1964
solenberg6d6e7c52016-04-13 09:07:30 -07001965// Test that SetSendParameters() does not alter a stream's send state.
1966TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1967 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001968 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001969
1970 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001971 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001972 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001973
1974 // Changing RTP header extensions will recreate the AudioSendStream.
1975 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001976 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001977 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001978 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001979
1980 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001981 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001983
1984 // Changing RTP header extensions will recreate the AudioSendStream.
1985 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001987 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001988}
1989
solenberg1ac56142015-10-13 03:58:19 -07001990// Test that we can create a channel and start playing out on it.
1991TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001992 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001993 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001994 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001996 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998}
1999
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002000// Test that we can add and remove send streams.
2001TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2002 SetupForMultiSendStream();
2003
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002004 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002005 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002006
solenbergc96df772015-10-21 13:01:53 -07002007 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002008 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002009 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002010 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002011 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002012 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013 }
tfarina5237aaf2015-11-10 23:44:30 -08002014 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015
solenbergc96df772015-10-21 13:01:53 -07002016 // Delete the send streams.
2017 for (uint32_t ssrc : kSsrcs4) {
2018 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002019 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002020 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 }
solenbergc96df772015-10-21 13:01:53 -07002022 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023}
2024
2025// Test SetSendCodecs correctly configure the codecs in all send streams.
2026TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2027 SetupForMultiSendStream();
2028
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002030 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002032 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002033 }
2034
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002035 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002037 parameters.codecs.push_back(kIsacCodec);
2038 parameters.codecs.push_back(kCn16000Codec);
2039 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002040 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002041
2042 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002043 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002044 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2045 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002046 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2047 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2048 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002049 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 }
2051
minyue7a973442016-10-20 03:27:12 -07002052 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002053 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002055 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002056 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2057 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002058 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2059 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2060 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002061 }
2062}
2063
2064// Test we can SetSend on all send streams correctly.
2065TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2066 SetupForMultiSendStream();
2067
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002068 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002069 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002071 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002072 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002073 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002074 }
2075
2076 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002077 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002078 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002080 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002081 }
2082
2083 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002084 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002085 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002086 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002087 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089}
2090
2091// Test we can set the correct statistics on all send streams.
2092TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2093 SetupForMultiSendStream();
2094
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002095 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002096 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002098 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 }
solenberg85a04962015-10-27 03:35:21 -07002100
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002101 // Create a receive stream to check that none of the send streams end up in
2102 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002103 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002104
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002106 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002107 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002108 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109
solenberg85a04962015-10-27 03:35:21 -07002110 // Check stats for the added streams.
2111 {
2112 cricket::VoiceMediaInfo info;
2113 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114
solenberg85a04962015-10-27 03:35:21 -07002115 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002116 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002117 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002118 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002119 }
hbos1acfbd22016-11-17 23:43:29 -08002120 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002121
2122 // We have added one receive stream. We should see empty stats.
2123 EXPECT_EQ(info.receivers.size(), 1u);
2124 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002125 }
solenberg1ac56142015-10-13 03:58:19 -07002126
solenberg2100c0b2017-03-01 11:29:29 -08002127 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002128 {
2129 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002130 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002131 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002132 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002133 EXPECT_EQ(0u, info.receivers.size());
2134 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002135
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002136 // Deliver a new packet - a default receive stream should be created and we
2137 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002138 {
2139 cricket::VoiceMediaInfo info;
2140 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2141 SetAudioReceiveStreamStats();
2142 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002143 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002144 EXPECT_EQ(1u, info.receivers.size());
2145 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002146 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002147 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002148}
2149
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002150// Test that we can add and remove receive streams, and do proper send/playout.
2151// We can receive on multiple streams while sending one stream.
2152TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002153 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002154
solenberg1ac56142015-10-13 03:58:19 -07002155 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002156 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002157 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158
solenberg1ac56142015-10-13 03:58:19 -07002159 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002160 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002161 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002162 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002163
solenberg1ac56142015-10-13 03:58:19 -07002164 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002165 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166
2167 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002168 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2169 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2170 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171
2172 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002173 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002174 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002175
2176 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002177 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002178 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2179 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180
aleloi84ef6152016-08-04 05:28:21 -07002181 // Restart playout and make sure recv streams are played out.
2182 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002183 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2184 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
aleloi84ef6152016-08-04 05:28:21 -07002186 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2188 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002189}
2190
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002191// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002192// and start sending on it.
2193TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002194 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002195 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2196 EXPECT_CALL(apm_gc_,
2197 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002198 SetSendParameters(send_parameters_);
2199 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002200 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002201 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002202 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002203}
2204
wu@webrtc.org97077a32013-10-25 21:18:33 +00002205TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002206 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002207 EXPECT_CALL(adm_,
2208 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002209 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2210 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002211 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2212 send_parameters_.options.tx_agc_digital_compression_gain =
2213 rtc::Optional<uint16_t>(9);
2214 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2215 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002216 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2217 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2218 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002219 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002220
2221 // Check interaction with adjust_agc_delta. Both should be respected, for
2222 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002223 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002224 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002225 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002226}
2227
wu@webrtc.org97077a32013-10-25 21:18:33 +00002228TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002229 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002230 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2231 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002232 send_parameters_.options.recording_sample_rate =
2233 rtc::Optional<uint32_t>(48000);
2234 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002235 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002236}
2237
minyue6b825df2016-10-31 04:08:32 -07002238TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2239 EXPECT_TRUE(SetupSendStream());
2240 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2241 send_parameters_.options.audio_network_adaptor_config =
2242 rtc::Optional<std::string>("1234");
2243 SetSendParameters(send_parameters_);
2244 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002245 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002246}
2247
2248TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2249 EXPECT_TRUE(SetupSendStream());
2250 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2251 send_parameters_.options.audio_network_adaptor_config =
2252 rtc::Optional<std::string>("1234");
2253 SetSendParameters(send_parameters_);
2254 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002255 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002256 cricket::AudioOptions options;
2257 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002258 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002259 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002260}
2261
2262TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2263 EXPECT_TRUE(SetupSendStream());
2264 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2265 send_parameters_.options.audio_network_adaptor_config =
2266 rtc::Optional<std::string>("1234");
2267 SetSendParameters(send_parameters_);
2268 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002269 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002270 const int initial_num = call_.GetNumCreatedSendStreams();
2271 cricket::AudioOptions options;
2272 options.audio_network_adaptor = rtc::Optional<bool>();
2273 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2274 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002275 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002276 // AudioSendStream not expected to be recreated.
2277 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2278 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002279 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002280}
2281
michaelt6672b262017-01-11 10:17:59 -08002282class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2283 : public WebRtcVoiceEngineTestFake {
2284 public:
2285 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2286 : WebRtcVoiceEngineTestFake(
2287 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2288 "Enabled/") {}
2289};
2290
2291TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2292 EXPECT_TRUE(SetupSendStream());
2293 cricket::AudioSendParameters parameters;
2294 parameters.codecs.push_back(kOpusCodec);
2295 SetSendParameters(parameters);
2296 const int initial_num = call_.GetNumCreatedSendStreams();
2297 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2298
2299 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2300 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002301 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2302 constexpr int kMinOverheadBps =
2303 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002304
2305 constexpr int kOpusMinBitrateBps = 6000;
2306 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002307 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002308 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002309 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002310 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002311
2312 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2313 parameters.options.audio_network_adaptor_config =
2314 rtc::Optional<std::string>("1234");
2315 SetSendParameters(parameters);
2316
ossu11bfc532017-02-16 05:37:06 -08002317 constexpr int kMinOverheadWithAnaBps =
2318 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002319
2320 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002321 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002322
minyuececec102017-03-27 13:04:25 -07002323 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002324 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002325}
2326
minyuececec102017-03-27 13:04:25 -07002327// This test is similar to
2328// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2329// additional field trial.
2330TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2331 SetRtpSendParameterUpdatesMaxBitrate) {
2332 EXPECT_TRUE(SetupSendStream());
2333 cricket::AudioSendParameters send_parameters;
2334 send_parameters.codecs.push_back(kOpusCodec);
2335 SetSendParameters(send_parameters);
2336
2337 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2338 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2339 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2340
2341 constexpr int kMaxBitrateBps = 6000;
2342 rtp_parameters.encodings[0].max_bitrate_bps =
2343 rtc::Optional<int>(kMaxBitrateBps);
2344 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2345
2346 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2347#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2348 constexpr int kMinOverhead = 3333;
2349#else
2350 constexpr int kMinOverhead = 6666;
2351#endif
2352 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2353}
2354
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002355// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002356// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002357TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002358 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002359 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002360}
2361
2362TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2363 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002364 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002365 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002366 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002367 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002368 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002369 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002370 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002371
solenberg85a04962015-10-27 03:35:21 -07002372 // Check stats for the added streams.
2373 {
2374 cricket::VoiceMediaInfo info;
2375 EXPECT_EQ(true, channel_->GetStats(&info));
2376
2377 // We have added one send stream. We should see the stats we've set.
2378 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002379 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002380 // We have added one receive stream. We should see empty stats.
2381 EXPECT_EQ(info.receivers.size(), 1u);
2382 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2383 }
solenberg1ac56142015-10-13 03:58:19 -07002384
solenberg566ef242015-11-06 15:34:49 -08002385 // Start sending - this affects some reported stats.
2386 {
2387 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002388 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002389 EXPECT_EQ(true, channel_->GetStats(&info));
2390 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002391 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002392 }
2393
solenberg2100c0b2017-03-01 11:29:29 -08002394 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002395 {
2396 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002397 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002398 EXPECT_EQ(true, channel_->GetStats(&info));
2399 EXPECT_EQ(1u, info.senders.size());
2400 EXPECT_EQ(0u, info.receivers.size());
2401 }
solenberg1ac56142015-10-13 03:58:19 -07002402
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002403 // Deliver a new packet - a default receive stream should be created and we
2404 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002405 {
2406 cricket::VoiceMediaInfo info;
2407 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2408 SetAudioReceiveStreamStats();
2409 EXPECT_EQ(true, channel_->GetStats(&info));
2410 EXPECT_EQ(1u, info.senders.size());
2411 EXPECT_EQ(1u, info.receivers.size());
2412 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002413 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002414 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415}
2416
2417// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002418// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002420 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002421 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2422 EXPECT_TRUE(AddRecvStream(kSsrcY));
2423 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424}
2425
2426// Test that the local SSRC is the same on sending and receiving channels if the
2427// receive channel is created before the send channel.
2428TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002429 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002430 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002432 cricket::StreamParams::CreateLegacy(kSsrcX)));
2433 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2434 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435}
2436
2437// Test that we can properly receive packets.
2438TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002439 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002440 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002442
2443 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2444 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445}
2446
2447// Test that we can properly receive packets on multiple streams.
2448TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002449 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002450 const uint32_t ssrc1 = 1;
2451 const uint32_t ssrc2 = 2;
2452 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002453 EXPECT_TRUE(AddRecvStream(ssrc1));
2454 EXPECT_TRUE(AddRecvStream(ssrc2));
2455 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002456 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002457 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002458 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002460 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461 }
mflodman3d7db262016-04-29 00:57:13 -07002462
2463 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2464 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2465 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2466
2467 EXPECT_EQ(s1.received_packets(), 0);
2468 EXPECT_EQ(s2.received_packets(), 0);
2469 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002470
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002472 EXPECT_EQ(s1.received_packets(), 0);
2473 EXPECT_EQ(s2.received_packets(), 0);
2474 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002475
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002477 EXPECT_EQ(s1.received_packets(), 1);
2478 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2479 EXPECT_EQ(s2.received_packets(), 0);
2480 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002481
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002483 EXPECT_EQ(s1.received_packets(), 1);
2484 EXPECT_EQ(s2.received_packets(), 1);
2485 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2486 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002487
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002488 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002489 EXPECT_EQ(s1.received_packets(), 1);
2490 EXPECT_EQ(s2.received_packets(), 1);
2491 EXPECT_EQ(s3.received_packets(), 1);
2492 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002493
mflodman3d7db262016-04-29 00:57:13 -07002494 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2495 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2496 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497}
2498
solenberg2100c0b2017-03-01 11:29:29 -08002499// Test that receiving on an unsignaled stream works (a stream is created).
2500TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002501 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002502 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2503
solenberg7e63ef02015-11-20 00:19:43 -08002504 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002505
2506 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002507 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2508 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002509}
2510
solenberg2100c0b2017-03-01 11:29:29 -08002511// Test that receiving N unsignaled stream works (streams will be created), and
2512// that packets are forwarded to them all.
2513TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002514 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002515 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002516 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2517
solenberg2100c0b2017-03-01 11:29:29 -08002518 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002519 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002520 rtc::SetBE32(&packet[8], ssrc);
2521 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002522
solenberg2100c0b2017-03-01 11:29:29 -08002523 // Verify we have one new stream for each loop iteration.
2524 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002525 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2526 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002527 }
mflodman3d7db262016-04-29 00:57:13 -07002528
solenberg2100c0b2017-03-01 11:29:29 -08002529 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002530 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002531 rtc::SetBE32(&packet[8], ssrc);
2532 DeliverPacket(packet, sizeof(packet));
2533
solenbergebb349d2017-03-13 05:46:15 -07002534 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002535 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2536 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2537 }
2538
2539 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2540 constexpr uint32_t kAnotherSsrc = 667;
2541 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002542 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002543
2544 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002545 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002546 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002547 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002548 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2549 EXPECT_EQ(2, streams[i]->received_packets());
2550 }
2551 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2552 EXPECT_EQ(1, streams[i]->received_packets());
2553 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002554 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002555}
2556
solenberg2100c0b2017-03-01 11:29:29 -08002557// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002558// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002559TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002560 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002561 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002562 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2563
2564 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002565 const uint32_t signaled_ssrc = 1;
2566 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002567 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002568 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002569 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2570 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002571 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002572
2573 // Note that the first unknown SSRC cannot be 0, because we only support
2574 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002575 const uint32_t unsignaled_ssrc = 7011;
2576 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002577 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002578 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2579 packet, sizeof(packet)));
2580 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2581
2582 DeliverPacket(packet, sizeof(packet));
2583 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2584
2585 rtc::SetBE32(&packet[8], signaled_ssrc);
2586 DeliverPacket(packet, sizeof(packet));
2587 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2588 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002589}
2590
solenberg4904fb62017-02-17 12:01:14 -08002591// Two tests to verify that adding a receive stream with the same SSRC as a
2592// previously added unsignaled stream will only recreate underlying stream
2593// objects if the stream parameters have changed.
2594TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2595 EXPECT_TRUE(SetupChannel());
2596
2597 // Spawn unsignaled stream with SSRC=1.
2598 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2599 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2600 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2601 sizeof(kPcmuFrame)));
2602
2603 // Verify that the underlying stream object in Call is not recreated when a
2604 // stream with SSRC=1 is added.
2605 const auto& streams = call_.GetAudioReceiveStreams();
2606 EXPECT_EQ(1, streams.size());
2607 int audio_receive_stream_id = streams.front()->id();
2608 EXPECT_TRUE(AddRecvStream(1));
2609 EXPECT_EQ(1, streams.size());
2610 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2611}
2612
2613TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2614 EXPECT_TRUE(SetupChannel());
2615
2616 // Spawn unsignaled stream with SSRC=1.
2617 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2618 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2619 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2620 sizeof(kPcmuFrame)));
2621
2622 // Verify that the underlying stream object in Call *is* recreated when a
2623 // stream with SSRC=1 is added, and which has changed stream parameters.
2624 const auto& streams = call_.GetAudioReceiveStreams();
2625 EXPECT_EQ(1, streams.size());
2626 int audio_receive_stream_id = streams.front()->id();
2627 cricket::StreamParams stream_params;
2628 stream_params.ssrcs.push_back(1);
2629 stream_params.sync_label = "sync_label";
2630 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2631 EXPECT_EQ(1, streams.size());
2632 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2633}
2634
solenberg0a617e22015-10-20 15:49:38 -07002635// Test that we properly handle failures to add a receive stream.
2636TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002637 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002638 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002639 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002640}
2641
solenberg0a617e22015-10-20 15:49:38 -07002642// Test that we properly handle failures to add a send stream.
2643TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002644 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002645 voe_.set_fail_create_channel(true);
2646 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2647}
2648
solenberg1ac56142015-10-13 03:58:19 -07002649// Test that AddRecvStream creates new stream.
2650TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002651 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002653 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002654 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655}
2656
2657// Test that after adding a recv stream, we do not decode more codecs than
2658// those previously passed into SetRecvCodecs.
2659TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002660 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002661 cricket::AudioRecvParameters parameters;
2662 parameters.codecs.push_back(kIsacCodec);
2663 parameters.codecs.push_back(kPcmuCodec);
2664 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002665 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002666 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2667 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2668 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002669}
2670
2671// Test that we properly clean up any streams that were added, even if
2672// not explicitly removed.
2673TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002674 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002675 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002676 EXPECT_TRUE(AddRecvStream(1));
2677 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002678 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2679 delete channel_;
2680 channel_ = NULL;
2681 EXPECT_EQ(0, voe_.GetNumChannels());
2682}
2683
wu@webrtc.org78187522013-10-07 23:32:02 +00002684TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002685 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002686 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002687}
2688
2689TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002690 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002691 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002692 // Manually delete channel to simulate a failure.
2693 int channel = voe_.GetLastChannel();
2694 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2695 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002696 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002697 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002698 EXPECT_NE(channel, new_channel);
2699 // The last created channel is deleted too.
2700 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002701}
2702
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002703// Test the InsertDtmf on default send stream as caller.
2704TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002705 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002706}
2707
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002708// Test the InsertDtmf on default send stream as callee
2709TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002710 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002711}
2712
2713// Test the InsertDtmf on specified send stream as caller.
2714TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002715 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002716}
2717
2718// Test the InsertDtmf on specified send stream as callee.
2719TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002720 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721}
2722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002723TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002724 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002725 EXPECT_CALL(adm_,
2726 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2727 EXPECT_CALL(adm_,
2728 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2729 EXPECT_CALL(adm_,
2730 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002731
solenberg246b8172015-12-08 09:50:23 -08002732 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2733 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734
solenberg246b8172015-12-08 09:50:23 -08002735 // Nothing set in AudioOptions, so everything should be as default.
2736 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002737 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002738 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002739 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2740 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002741
2742 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002743 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2744 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002745 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002746 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747
2748 // Turn echo cancellation back on, with settings, and make sure
2749 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002750 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2751 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002752 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002753 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002755 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2756 // control.
solenberg76377c52017-02-21 00:54:31 -08002757 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2758 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002759 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002760 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002761
2762 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002763 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2764 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002765 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2766 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2767 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002768 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002769
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002770 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002771 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002773 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002774 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002775
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002777 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002781 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002782 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002783
2784 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002785 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2787 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002789 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2790 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002791 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002792
2793 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002794 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2795 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2797 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2799 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2800 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002801 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2802 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2803 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2804 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002805 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002806 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807
solenberg1ac56142015-10-13 03:58:19 -07002808 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002809 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2814 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2815 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002816 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817}
2818
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002819TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002820 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002821 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002822 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002823 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002824 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002825 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002826 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002827 EXPECT_CALL(adm_,
2828 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2829 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2830 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002831 webrtc::AudioProcessing::Config apm_config;
2832 EXPECT_CALL(*apm_, GetConfig())
2833 .Times(10)
2834 .WillRepeatedly(ReturnPointee(&apm_config));
2835 EXPECT_CALL(*apm_, ApplyConfig(_))
2836 .Times(10)
2837 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002838 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002839
kwiberg686a8ef2016-02-26 03:00:35 -08002840 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002841 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002842 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002843 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002844 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002845 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002846
2847 // Have to add a stream to make SetSend work.
2848 cricket::StreamParams stream1;
2849 stream1.ssrcs.push_back(1);
2850 channel1->AddSendStream(stream1);
2851 cricket::StreamParams stream2;
2852 stream2.ssrcs.push_back(2);
2853 channel2->AddSendStream(stream2);
2854
2855 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002856 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002857 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2858 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2859 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002860 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2861 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2862 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2863 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2864 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002865 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002866 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002867 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002868 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869
2870 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002872 parameters_options_no_ns.options.noise_suppression =
2873 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002874 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2876 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2878 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002879 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002880 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002881 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2882 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2883 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002884 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002885
2886 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002887 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002888 parameters_options_no_agc.options.auto_gain_control =
2889 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002890 EXPECT_CALL(adm_, SetAGC(false)).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(false)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002895 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002896 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2897 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2898 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002899 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900
solenberg76377c52017-02-21 00:54:31 -08002901 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2903 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2904 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2905 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002906 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907
solenberg76377c52017-02-21 00:54:31 -08002908 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2909 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2910 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2911 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002913 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914
solenberg76377c52017-02-21 00:54:31 -08002915 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2916 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2918 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002920 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002923 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2924 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002925 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002926 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002927 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002928 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002929 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2930 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2931 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2932 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2933 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002934 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002935 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2936 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2937 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002938 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002939}
2940
wu@webrtc.orgde305012013-10-31 15:40:38 +00002941// This test verifies DSCP settings are properly applied on voice media channel.
2942TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002943 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002944 cricket::FakeNetworkInterface network_interface;
2945 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002946 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002947
peahb1c9d1d2017-07-25 15:45:24 -07002948 webrtc::AudioProcessing::Config apm_config;
2949 EXPECT_CALL(*apm_, GetConfig())
2950 .Times(3)
2951 .WillRepeatedly(ReturnPointee(&apm_config));
2952 EXPECT_CALL(*apm_, ApplyConfig(_))
2953 .Times(3)
2954 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002955 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002956
solenbergbc37fc82016-04-04 09:54:44 -07002957 channel.reset(
2958 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002959 channel->SetInterface(&network_interface);
2960 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2961 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2962
2963 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002964 channel.reset(
2965 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002966 channel->SetInterface(&network_interface);
2967 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2968
2969 // Verify that setting the option to false resets the
2970 // DiffServCodePoint.
2971 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002972 channel.reset(
2973 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002974 channel->SetInterface(&network_interface);
2975 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2976 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2977
2978 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002979}
2980
solenberg1ac56142015-10-13 03:58:19 -07002981TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002982 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983 cricket::WebRtcVoiceMediaChannel* media_channel =
2984 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002985 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002986 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002987 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002988 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2989 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2990 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002991 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002992 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993}
2994
solenberg1ac56142015-10-13 03:58:19 -07002995TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002996 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002998 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2999 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3000 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003001 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003002 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003003 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3004 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003005 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003006 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003007 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003008 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003009}
3010
solenberg4bac9c52015-10-09 02:32:53 -07003011TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003012 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003013 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003015 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003016 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003017 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3018 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3019 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003020}
3021
solenberg2100c0b2017-03-01 11:29:29 -08003022TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003023 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003024
3025 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003026 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003027 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3028
3029 // Should remember the volume "2" which will be set on new unsignaled streams,
3030 // and also set the gain to 2 on existing unsignaled streams.
3031 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3032 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3033
3034 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3035 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3036 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3037 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3038 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3039 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3040
3041 // Setting gain with SSRC=0 should affect all unsignaled streams.
3042 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003043 if (kMaxUnsignaledRecvStreams > 1) {
3044 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3045 }
solenberg2100c0b2017-03-01 11:29:29 -08003046 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3047
3048 // Setting gain on an individual stream affects only that.
3049 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003050 if (kMaxUnsignaledRecvStreams > 1) {
3051 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3052 }
solenberg2100c0b2017-03-01 11:29:29 -08003053 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003054}
3055
pbos8fc7fa72015-07-15 08:02:58 -07003056TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003057 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003058 const std::string kSyncLabel = "AvSyncLabel";
3059
solenbergff976312016-03-30 23:28:51 -07003060 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003061 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3062 sp.sync_label = kSyncLabel;
3063 // Creating two channels to make sure that sync label is set properly for both
3064 // the default voice channel and following ones.
3065 EXPECT_TRUE(channel_->AddRecvStream(sp));
3066 sp.ssrcs[0] += 1;
3067 EXPECT_TRUE(channel_->AddRecvStream(sp));
3068
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003069 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003070 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003071 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003072 << "SyncGroup should be set based on sync_label";
3073 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003074 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003075 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003076}
3077
solenberg3a941542015-11-16 07:34:50 -08003078// TODO(solenberg): Remove, once recv streams are configured through Call.
3079// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003080TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003081 // Test that setting the header extensions results in the expected state
3082 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003083 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003084 ssrcs.push_back(223);
3085 ssrcs.push_back(224);
3086
solenbergff976312016-03-30 23:28:51 -07003087 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003088 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003089 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003090 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 cricket::StreamParams::CreateLegacy(ssrc)));
3092 }
3093
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003094 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003095 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003096 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097 EXPECT_NE(nullptr, s);
3098 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3099 }
3100
3101 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003102 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003103 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003104 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003105 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003106 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003107 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003108 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003109 EXPECT_NE(nullptr, s);
3110 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003111 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3112 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003113 for (const auto& s_ext : s_exts) {
3114 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003115 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003116 }
3117 }
3118 }
3119 }
3120
3121 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003122 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003123 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003124 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003125 EXPECT_NE(nullptr, s);
3126 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3127 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128}
3129
3130TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3131 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003132 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003133 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003134 static const unsigned char kRtcp[] = {
3135 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3136 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3139 };
jbaucheec21bd2016-03-20 06:15:43 -07003140 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003141
solenbergff976312016-03-30 23:28:51 -07003142 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143 cricket::WebRtcVoiceMediaChannel* media_channel =
3144 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003145 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 EXPECT_TRUE(media_channel->AddRecvStream(
3147 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3148
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003149 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003150 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003151 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003152 EXPECT_EQ(0, s->received_packets());
3153 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3154 EXPECT_EQ(1, s->received_packets());
3155 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3156 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003157}
Minyue2013aec2015-05-13 14:14:42 +02003158
solenberg0a617e22015-10-20 15:49:38 -07003159// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003160// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003161TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003162 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003163 EXPECT_TRUE(AddRecvStream(kSsrcY));
3164 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003165 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003166 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3167 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3168 EXPECT_TRUE(AddRecvStream(kSsrcW));
3169 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003170}
3171
solenberg7602aab2016-11-14 11:30:07 -08003172TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3173 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003174 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003175 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003176 cricket::StreamParams::CreateLegacy(kSsrcY)));
3177 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3178 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3179 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003180 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003181 cricket::StreamParams::CreateLegacy(kSsrcW)));
3182 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3183 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003184}
stefan658910c2015-09-03 05:48:32 -07003185
deadbeef884f5852016-01-15 09:20:04 -08003186TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003187 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003188 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3189 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003190
3191 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003192 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3193 EXPECT_TRUE(AddRecvStream(kSsrcX));
3194 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003195
3196 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003197 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3198 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003199
3200 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003201 channel_->SetRawAudioSink(kSsrcX, nullptr);
3202 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003203}
3204
solenberg2100c0b2017-03-01 11:29:29 -08003205TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003206 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003207 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3208 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003209 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3210 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003211
3212 // Should be able to set a default sink even when no stream exists.
3213 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3214
solenberg2100c0b2017-03-01 11:29:29 -08003215 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3216 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003217 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003218 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003219
3220 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003221 channel_->SetRawAudioSink(kSsrc0, nullptr);
3222 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003223
3224 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003225 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3226 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003227
3228 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003229 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003230 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3232
3233 // Spawn another unsignaled stream - it should be assigned the default sink
3234 // and the previous unsignaled stream should lose it.
3235 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3236 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3237 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3238 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003239 if (kMaxUnsignaledRecvStreams > 1) {
3240 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3241 }
solenberg2100c0b2017-03-01 11:29:29 -08003242 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3243
3244 // Reset the default sink - the second unsignaled stream should lose it.
3245 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003246 if (kMaxUnsignaledRecvStreams > 1) {
3247 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3248 }
solenberg2100c0b2017-03-01 11:29:29 -08003249 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3250
3251 // Try setting the default sink while two streams exists.
3252 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003253 if (kMaxUnsignaledRecvStreams > 1) {
3254 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3255 }
solenberg2100c0b2017-03-01 11:29:29 -08003256 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3257
3258 // Try setting the sink for the first unsignaled stream using its known SSRC.
3259 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003260 if (kMaxUnsignaledRecvStreams > 1) {
3261 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3262 }
solenberg2100c0b2017-03-01 11:29:29 -08003263 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003264 if (kMaxUnsignaledRecvStreams > 1) {
3265 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3266 }
deadbeef884f5852016-01-15 09:20:04 -08003267}
3268
skvlad7a43d252016-03-22 15:32:27 -07003269// Test that, just like the video channel, the voice channel communicates the
3270// network state to the call.
3271TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003272 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003273
3274 EXPECT_EQ(webrtc::kNetworkUp,
3275 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3276 EXPECT_EQ(webrtc::kNetworkUp,
3277 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3278
3279 channel_->OnReadyToSend(false);
3280 EXPECT_EQ(webrtc::kNetworkDown,
3281 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3282 EXPECT_EQ(webrtc::kNetworkUp,
3283 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3284
3285 channel_->OnReadyToSend(true);
3286 EXPECT_EQ(webrtc::kNetworkUp,
3287 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3288 EXPECT_EQ(webrtc::kNetworkUp,
3289 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3290}
3291
aleloi18e0b672016-10-04 02:45:47 -07003292// Test that playout is still started after changing parameters
3293TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3294 SetupRecvStream();
3295 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003296 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003297
3298 // Changing RTP header extensions will recreate the AudioReceiveStream.
3299 cricket::AudioRecvParameters parameters;
3300 parameters.extensions.push_back(
3301 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3302 channel_->SetRecvParameters(parameters);
3303
solenberg2100c0b2017-03-01 11:29:29 -08003304 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003305}
3306
stefan658910c2015-09-03 05:48:32 -07003307// Tests that the library initializes and shuts down properly.
3308TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003309 // If the VoiceEngine wants to gather available codecs early, that's fine but
3310 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003311 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3312 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003313 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003314 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003315 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003316 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003317 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003318 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003319 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003320 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3321 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003322 EXPECT_TRUE(channel != nullptr);
3323 delete channel;
solenbergff976312016-03-30 23:28:51 -07003324}
stefan658910c2015-09-03 05:48:32 -07003325
solenbergff976312016-03-30 23:28:51 -07003326// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003327TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3328 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3329 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3330 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003331 // Return 100ms just in case this function gets called. If we don't,
3332 // we could enter a tight loop since the mock would return 0.
3333 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003334 {
peaha9cc40b2017-06-29 08:32:09 -07003335 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3336 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003337 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003338 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003339 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003340 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003341 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003342 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003343 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003344 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3345 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3346 EXPECT_TRUE(channel != nullptr);
3347 delete channel;
3348 }
stefan658910c2015-09-03 05:48:32 -07003349}
3350
ossu20a4b3f2017-04-27 02:08:52 -07003351// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3352TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003353 // TODO(ossu): Why are the payload types of codecs with non-static payload
3354 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003355 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3356 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003357 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003358 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003359 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003360 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003361 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003362 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3363 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3364 (clockrate == 0 || codec.clockrate == clockrate);
3365 };
3366 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003367 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003368 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003369 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003370 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003371 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003372 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003373 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003374 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003375 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003376 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(126, codec.id);
3378 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3379 // Remove these checks once both send and receive side assigns payload types
3380 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003381 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003382 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003383 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003384 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003385 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003386 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003387 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003388 EXPECT_EQ(111, codec.id);
3389 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3390 EXPECT_EQ("10", codec.params.find("minptime")->second);
3391 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3392 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003393 }
3394 }
stefan658910c2015-09-03 05:48:32 -07003395}
3396
3397// Tests that VoE supports at least 32 channels
3398TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003399 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3400 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003401 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003402 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003403 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003404 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003405 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003406 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003407 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003408
3409 cricket::VoiceMediaChannel* channels[32];
3410 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003411 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003412 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3413 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003414 if (!channel)
3415 break;
stefan658910c2015-09-03 05:48:32 -07003416 channels[num_channels++] = channel;
3417 }
3418
tfarina5237aaf2015-11-10 23:44:30 -08003419 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003420 EXPECT_EQ(expected, num_channels);
3421
3422 while (num_channels > 0) {
3423 delete channels[--num_channels];
3424 }
stefan658910c2015-09-03 05:48:32 -07003425}
3426
3427// Test that we set our preferred codecs properly.
3428TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003429 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3430 // - Check that our builtin codecs are usable by Channel.
3431 // - The codecs provided by the engine is usable by Channel.
3432 // It does not check that the codecs in the RecvParameters are actually
3433 // what we sent in - though it's probably reasonable to expect so, if
3434 // SetRecvParameters returns true.
3435 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003436 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3437 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003438 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003439 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003440 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003441 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003442 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003443 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003444 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003445 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3446 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003447 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003448 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003449 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003450}
ossu9def8002017-02-09 05:14:32 -08003451
3452TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3453 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003454 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3455 {48000, 2, 16000, 10000, 20000}};
3456 spec1.info.allow_comfort_noise = false;
3457 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003458 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003459 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3460 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003461 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003462 specs.push_back(webrtc::AudioCodecSpec{
3463 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3464 {16000, 1, 13300}});
3465 specs.push_back(
3466 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3467 specs.push_back(
3468 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003469
ossueb1fde42017-05-02 06:46:30 -07003470 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3471 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3472 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003473 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003474 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003475 .WillOnce(Return(specs));
3476
peaha9cc40b2017-06-29 08:32:09 -07003477 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3478 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003479 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003480 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003481 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003482 auto codecs = engine.recv_codecs();
3483 EXPECT_EQ(11, codecs.size());
3484
3485 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3486 // check the actual values safely, to provide better test results.
3487 auto get_codec =
3488 [&codecs](size_t index) -> const cricket::AudioCodec& {
3489 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3490 if (codecs.size() > index)
3491 return codecs[index];
3492 return missing_codec;
3493 };
3494
3495 // Ensure the general codecs are generated first and in order.
3496 for (size_t i = 0; i != specs.size(); ++i) {
3497 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3498 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3499 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3500 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3501 }
3502
3503 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003504 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003505 auto find_codec =
3506 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3507 for (size_t i = 0; i != codecs.size(); ++i) {
3508 const cricket::AudioCodec& codec = codecs[i];
3509 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3510 codec.clockrate == format.clockrate_hz &&
3511 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003512 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003513 }
3514 }
3515 return -1;
3516 };
3517
3518 // Ensure all supplementary codecs are generated last. Their internal ordering
3519 // is not important.
3520 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3521 const int num_specs = static_cast<int>(specs.size());
3522 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3523 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3524 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3525 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3526 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3527 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3528 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3529}