blob: ef56473376dcaafa75f94965d41a62772fb49351 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
16#include "call/call.h"
17#include "logging/rtc_event_log/rtc_event_log.h"
18#include "media/base/fakemediaengine.h"
19#include "media/base/fakenetworkinterface.h"
20#include "media/base/fakertp.h"
21#include "media/base/mediaconstants.h"
22#include "media/engine/fakewebrtccall.h"
23#include "media/engine/fakewebrtcvoiceengine.h"
24#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
30#include "rtc_base/safe_conversions.h"
31#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
36#include "voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
46
solenberg418b7d32017-06-13 00:38:27 -070047constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070048
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
50const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070051const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
53const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
55const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080056const cricket::AudioCodec
57 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
58const cricket::AudioCodec
59 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
60
solenberg2100c0b2017-03-01 11:29:29 -080061const uint32_t kSsrc0 = 0;
62const uint32_t kSsrc1 = 1;
63const uint32_t kSsrcX = 0x99;
64const uint32_t kSsrcY = 0x17;
65const uint32_t kSsrcZ = 0x42;
66const uint32_t kSsrcW = 0x02;
67const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
solenberg971cab02016-06-14 10:02:41 -070069constexpr int kRtpHistoryMs = 5000;
70
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071class FakeVoEWrapper : public cricket::VoEWrapper {
72 public:
73 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070074 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075 }
76};
skvlad11a9cbf2016-10-07 11:53:05 -070077
solenberg76377c52017-02-21 00:54:31 -080078class MockTransmitMixer : public webrtc::voe::TransmitMixer {
79 public:
80 MockTransmitMixer() = default;
81 virtual ~MockTransmitMixer() = default;
82
83 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
84};
solenberg9a5f032222017-03-15 06:14:12 -070085
86void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
87 RTC_DCHECK(adm);
Niels Möller6f72f562017-10-19 13:15:17 +020088 EXPECT_CALL(*adm, AddRef()).Times(1);
89 EXPECT_CALL(*adm, Release())
90 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -070091#if !defined(WEBRTC_IOS)
92 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
solenberg9a5f032222017-03-15 06:14:12 -070093#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
Oskar Sundbom78807582017-11-16 11:09:55 +0100373 parameters.encodings[0].max_bitrate_bps = 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";
Oskar Sundbom78807582017-11-16 11:09:55 +0100537 stats.codec_payload_type = 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;
Oskar Sundbom78807582017-11-16 11:09:55 +0100549 stats.ana_statistics.bitrate_action_counter = 321;
550 stats.ana_statistics.channel_action_counter = 432;
551 stats.ana_statistics.dtx_action_counter = 543;
552 stats.ana_statistics.fec_action_counter = 654;
553 stats.ana_statistics.frame_length_increase_counter = 765;
554 stats.ana_statistics.frame_length_decrease_counter = 876;
555 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700556 stats.typing_noise_detected = true;
557 return stats;
558 }
559 void SetAudioSendStreamStats() {
560 for (auto* s : call_.GetAudioSendStreams()) {
561 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200562 }
solenberg85a04962015-10-27 03:35:21 -0700563 }
solenberg566ef242015-11-06 15:34:49 -0800564 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
565 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700566 const auto stats = GetAudioSendStreamStats();
567 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
568 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
569 EXPECT_EQ(info.packets_sent, stats.packets_sent);
570 EXPECT_EQ(info.packets_lost, stats.packets_lost);
571 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
572 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800573 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700574 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
575 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
576 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
577 EXPECT_EQ(info.audio_level, stats.audio_level);
578 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
579 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
580 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
581 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
582 EXPECT_EQ(info.echo_return_loss_enhancement,
583 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700584 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800585 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
586 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700587 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
588 stats.ana_statistics.bitrate_action_counter);
589 EXPECT_EQ(info.ana_statistics.channel_action_counter,
590 stats.ana_statistics.channel_action_counter);
591 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
592 stats.ana_statistics.dtx_action_counter);
593 EXPECT_EQ(info.ana_statistics.fec_action_counter,
594 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700595 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
596 stats.ana_statistics.frame_length_increase_counter);
597 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
598 stats.ana_statistics.frame_length_decrease_counter);
599 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
600 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800601 EXPECT_EQ(info.typing_noise_detected,
602 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700603 }
604
605 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
606 webrtc::AudioReceiveStream::Stats stats;
607 stats.remote_ssrc = 123;
608 stats.bytes_rcvd = 456;
609 stats.packets_rcvd = 768;
610 stats.packets_lost = 101;
611 stats.fraction_lost = 23.45f;
612 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100613 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700614 stats.ext_seqnum = 678;
615 stats.jitter_ms = 901;
616 stats.jitter_buffer_ms = 234;
617 stats.jitter_buffer_preferred_ms = 567;
618 stats.delay_estimate_ms = 890;
619 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700620 stats.total_samples_received = 5678901;
621 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200622 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200623 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700624 stats.expand_rate = 5.67f;
625 stats.speech_expand_rate = 8.90f;
626 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200627 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700628 stats.accelerate_rate = 4.56f;
629 stats.preemptive_expand_rate = 7.89f;
630 stats.decoding_calls_to_silence_generator = 12;
631 stats.decoding_calls_to_neteq = 345;
632 stats.decoding_normal = 67890;
633 stats.decoding_plc = 1234;
634 stats.decoding_cng = 5678;
635 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700636 stats.decoding_muted_output = 3456;
637 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200638 return stats;
639 }
640 void SetAudioReceiveStreamStats() {
641 for (auto* s : call_.GetAudioReceiveStreams()) {
642 s->SetStats(GetAudioReceiveStreamStats());
643 }
644 }
645 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700646 const auto stats = GetAudioReceiveStreamStats();
647 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
648 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
649 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
650 EXPECT_EQ(info.packets_lost, stats.packets_lost);
651 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
652 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800653 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700654 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
655 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
656 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200657 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700658 stats.jitter_buffer_preferred_ms);
659 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
660 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700661 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
662 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200663 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200664 EXPECT_EQ(info.jitter_buffer_delay_seconds,
665 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700666 EXPECT_EQ(info.expand_rate, stats.expand_rate);
667 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
668 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200669 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700670 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
671 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200672 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700673 stats.decoding_calls_to_silence_generator);
674 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
675 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
676 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
677 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
678 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700679 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700680 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200681 }
hbos1acfbd22016-11-17 23:43:29 -0800682 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
683 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
684 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
685 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
686 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
687 codec.ToCodecParameters());
688 }
689 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
690 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
691 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
692 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
693 codec.ToCodecParameters());
694 }
695 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200696
peah8271d042016-11-22 07:24:52 -0800697 bool IsHighPassFilterEnabled() {
698 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
699 }
700
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700702 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700703 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800704 webrtc::test::MockGainControl& apm_gc_;
705 webrtc::test::MockEchoCancellation& apm_ec_;
706 webrtc::test::MockNoiseSuppression& apm_ns_;
707 webrtc::test::MockVoiceDetection& apm_vd_;
708 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700709 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200710 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700712 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700713 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200714 cricket::AudioSendParameters send_parameters_;
715 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800716 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700717 webrtc::AudioProcessing::Config apm_config_;
718
stefanba4c0e42016-02-04 04:12:24 -0800719 private:
720 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721};
722
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723// Tests that we can create and destroy a channel.
724TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700725 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726}
727
solenberg31fec402016-05-06 02:13:12 -0700728// Test that we can add a send stream and that it has the correct defaults.
729TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
730 EXPECT_TRUE(SetupChannel());
731 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800732 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
733 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
734 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700735 EXPECT_EQ("", config.rtp.c_name);
736 EXPECT_EQ(0u, config.rtp.extensions.size());
737 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
738 config.send_transport);
739}
740
741// Test that we can add a receive stream and that it has the correct defaults.
742TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
743 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800744 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700745 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800746 GetRecvStreamConfig(kSsrcX);
747 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700748 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
749 EXPECT_FALSE(config.rtp.transport_cc);
750 EXPECT_EQ(0u, config.rtp.extensions.size());
751 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
752 config.rtcp_send_transport);
753 EXPECT_EQ("", config.sync_group);
754}
755
stefanba4c0e42016-02-04 04:12:24 -0800756TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700757 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800758 bool opus_found = false;
759 for (cricket::AudioCodec codec : codecs) {
760 if (codec.name == "opus") {
761 EXPECT_TRUE(HasTransportCc(codec));
762 opus_found = true;
763 }
764 }
765 EXPECT_TRUE(opus_found);
766}
767
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768// Test that we set our inbound codecs properly, including changing PT.
769TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700770 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200771 cricket::AudioRecvParameters parameters;
772 parameters.codecs.push_back(kIsacCodec);
773 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800774 parameters.codecs.push_back(kTelephoneEventCodec1);
775 parameters.codecs.push_back(kTelephoneEventCodec2);
776 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 parameters.codecs[2].id = 126;
778 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800779 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700780 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
781 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
782 {{0, {"PCMU", 8000, 1}},
783 {106, {"ISAC", 16000, 1}},
784 {126, {"telephone-event", 8000, 1}},
785 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
788// Test that we fail to set an unknown inbound codec.
789TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700790 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200791 cricket::AudioRecvParameters parameters;
792 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700793 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
797// Test that we fail if we have duplicate types in the inbound list.
798TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
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(kCn16000Codec);
803 parameters.codecs[1].id = kIsacCodec.id;
804 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805}
806
807// Test that we can decode OPUS without stereo parameters.
808TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700809 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200810 cricket::AudioRecvParameters parameters;
811 parameters.codecs.push_back(kIsacCodec);
812 parameters.codecs.push_back(kPcmuCodec);
813 parameters.codecs.push_back(kOpusCodec);
814 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800815 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700816 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
817 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
818 {{0, {"PCMU", 8000, 1}},
819 {103, {"ISAC", 16000, 1}},
820 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821}
822
823// Test that we can decode OPUS with stereo = 0.
824TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700825 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 cricket::AudioRecvParameters parameters;
827 parameters.codecs.push_back(kIsacCodec);
828 parameters.codecs.push_back(kPcmuCodec);
829 parameters.codecs.push_back(kOpusCodec);
830 parameters.codecs[2].params["stereo"] = "0";
831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800832 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700833 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
834 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
835 {{0, {"PCMU", 8000, 1}},
836 {103, {"ISAC", 16000, 1}},
837 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
840// Test that we can decode OPUS with stereo = 1.
841TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700842 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200843 cricket::AudioRecvParameters parameters;
844 parameters.codecs.push_back(kIsacCodec);
845 parameters.codecs.push_back(kPcmuCodec);
846 parameters.codecs.push_back(kOpusCodec);
847 parameters.codecs[2].params["stereo"] = "1";
848 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800849 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700850 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
851 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
852 {{0, {"PCMU", 8000, 1}},
853 {103, {"ISAC", 16000, 1}},
854 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855}
856
857// Test that changes to recv codecs are applied to all streams.
858TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700859 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200860 cricket::AudioRecvParameters parameters;
861 parameters.codecs.push_back(kIsacCodec);
862 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800863 parameters.codecs.push_back(kTelephoneEventCodec1);
864 parameters.codecs.push_back(kTelephoneEventCodec2);
865 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200866 parameters.codecs[2].id = 126;
867 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700868 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
869 EXPECT_TRUE(AddRecvStream(ssrc));
870 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
871 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
872 {{0, {"PCMU", 8000, 1}},
873 {106, {"ISAC", 16000, 1}},
874 {126, {"telephone-event", 8000, 1}},
875 {107, {"telephone-event", 32000, 1}}})));
876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877}
878
879TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700880 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 cricket::AudioRecvParameters parameters;
882 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885
solenberg2100c0b2017-03-01 11:29:29 -0800886 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800887 ASSERT_EQ(1, dm.count(106));
888 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889}
890
891// Test that we can apply the same set of codecs again while playing.
892TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700893 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200894 cricket::AudioRecvParameters parameters;
895 parameters.codecs.push_back(kIsacCodec);
896 parameters.codecs.push_back(kCn16000Codec);
897 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700898 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
deadbeefcb383672017-04-26 16:28:42 -0700901 // Remapping a payload type to a different codec should fail.
902 parameters.codecs[0] = kOpusCodec;
903 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800905 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906}
907
908// Test that we can add a codec while playing.
909TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700910 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200911 cricket::AudioRecvParameters parameters;
912 parameters.codecs.push_back(kIsacCodec);
913 parameters.codecs.push_back(kCn16000Codec);
914 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700915 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 parameters.codecs.push_back(kOpusCodec);
918 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800919 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920}
921
deadbeefcb383672017-04-26 16:28:42 -0700922// Test that we accept adding the same codec with a different payload type.
923// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
924TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
925 EXPECT_TRUE(SetupRecvStream());
926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
928 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
929
930 ++parameters.codecs[0].id;
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932}
933
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700935 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000937 // Test that when autobw is enabled, bitrate is kept as the default
938 // value. autobw is enabled for the following tests because the target
939 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940
941 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700942 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
ossu20a4b3f2017-04-27 02:08:52 -0700947 // opus, default bitrate == 32000 in mono.
948 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000951TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700952 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700955 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
956 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700957 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
961 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
962 // Rates above the max (510000) should be capped.
963 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000966TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700967 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000968
969 // Test that we can only set a maximum bitrate for a fixed-rate codec
970 // if it's bigger than the fixed rate.
971
972 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700973 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
974 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
975 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
976 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000980}
981
982TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700983 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200984 const int kDesiredBitrate = 128000;
985 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700986 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700988 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000989
990 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800991 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
solenberg2100c0b2017-03-01 11:29:29 -0800993 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000994}
995
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996// Test that bitrate cannot be set for CBR codecs.
997// Bitrate is ignored if it is higher than the fixed bitrate.
998// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001000 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001
1002 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001003 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001004 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001005
1006 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001007 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001008 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009
1010 send_parameters_.max_bandwidth_bps = 128;
1011 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001012 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013}
1014
skvlade0d46372016-04-07 22:59:22 -07001015// Test that the per-stream bitrate limit and the global
1016// bitrate limit both apply.
1017TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1018 EXPECT_TRUE(SetupSendStream());
1019
ossu20a4b3f2017-04-27 02:08:52 -07001020 // opus, default bitrate == 32000.
1021 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001022 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1023 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1024 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1025
1026 // CBR codecs allow both maximums to exceed the bitrate.
1027 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1028 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1029 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1030 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1031
1032 // CBR codecs don't allow per stream maximums to be too low.
1033 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1035}
1036
1037// Test that an attempt to set RtpParameters for a stream that does not exist
1038// fails.
1039TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1040 EXPECT_TRUE(SetupChannel());
1041 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001042 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001043 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1044
1045 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001046 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001047}
1048
1049TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001050 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001051 // This test verifies that setting RtpParameters succeeds only if
1052 // the structure contains exactly one encoding.
1053 // TODO(skvlad): Update this test when we start supporting setting parameters
1054 // for each encoding individually.
1055
1056 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001057 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001058 // Two or more encodings should result in failure.
1059 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001060 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001061 // Zero encodings should also fail.
1062 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001064}
1065
1066// Changing the SSRC through RtpParameters is not allowed.
1067TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1068 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001069 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001070 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001072}
1073
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001074// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001076TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1077 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001078 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001079 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001080 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001082 ASSERT_EQ(1u, parameters.encodings.size());
1083 ASSERT_TRUE(parameters.encodings[0].active);
1084 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1086 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087
1088 // Now change it back to active and verify we resume sending.
1089 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1091 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092}
1093
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001094// Test that SetRtpSendParameters configures the correct encoding channel for
1095// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001096TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1097 SetupForMultiSendStream();
1098 // Create send streams.
1099 for (uint32_t ssrc : kSsrcs4) {
1100 EXPECT_TRUE(
1101 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1102 }
1103 // Configure one stream to be limited by the stream config, another to be
1104 // limited by the global max, and the third one with no per-stream limit
1105 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001106 SetGlobalMaxBitrate(kOpusCodec, 32000);
1107 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1108 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001109 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1110
ossu20a4b3f2017-04-27 02:08:52 -07001111 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1112 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1113 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001114
1115 // Remove the global cap; the streams should switch to their respective
1116 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001117 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001118 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1119 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1120 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001121}
1122
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001123// Test that GetRtpSendParameters returns the currently configured codecs.
1124TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001125 EXPECT_TRUE(SetupSendStream());
1126 cricket::AudioSendParameters parameters;
1127 parameters.codecs.push_back(kIsacCodec);
1128 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001129 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001130
solenberg2100c0b2017-03-01 11:29:29 -08001131 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001132 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1134 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135}
1136
deadbeefcb443432016-12-12 11:12:36 -08001137// Test that GetRtpSendParameters returns an SSRC.
1138TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1139 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001140 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001141 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001142 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001143}
1144
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001145// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001146TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001147 EXPECT_TRUE(SetupSendStream());
1148 cricket::AudioSendParameters parameters;
1149 parameters.codecs.push_back(kIsacCodec);
1150 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001151 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152
solenberg2100c0b2017-03-01 11:29:29 -08001153 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
1155 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001156 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001159 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1160 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001161}
1162
minyuececec102017-03-27 13:04:25 -07001163// Test that max_bitrate_bps in send stream config gets updated correctly when
1164// SetRtpSendParameters is called.
1165TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1166 webrtc::test::ScopedFieldTrials override_field_trials(
1167 "WebRTC-Audio-SendSideBwe/Enabled/");
1168 EXPECT_TRUE(SetupSendStream());
1169 cricket::AudioSendParameters send_parameters;
1170 send_parameters.codecs.push_back(kOpusCodec);
1171 SetSendParameters(send_parameters);
1172
1173 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1174 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1175 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1176
1177 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001178 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001179 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1180
1181 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1182 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1183}
1184
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001185// Test that GetRtpReceiveParameters returns the currently configured codecs.
1186TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1187 EXPECT_TRUE(SetupRecvStream());
1188 cricket::AudioRecvParameters parameters;
1189 parameters.codecs.push_back(kIsacCodec);
1190 parameters.codecs.push_back(kPcmuCodec);
1191 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1192
1193 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001194 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001195 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1196 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1197 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1198}
1199
deadbeefcb443432016-12-12 11:12:36 -08001200// Test that GetRtpReceiveParameters returns an SSRC.
1201TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1202 EXPECT_TRUE(SetupRecvStream());
1203 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001204 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001205 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001206 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001207}
1208
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001209// Test that if we set/get parameters multiple times, we get the same results.
1210TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1211 EXPECT_TRUE(SetupRecvStream());
1212 cricket::AudioRecvParameters parameters;
1213 parameters.codecs.push_back(kIsacCodec);
1214 parameters.codecs.push_back(kPcmuCodec);
1215 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1216
1217 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001218 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001219
1220 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001221 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001222
1223 // ... And this shouldn't change the params returned by
1224 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001225 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1226 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001227}
1228
deadbeef3bc15102017-04-20 19:25:07 -07001229// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1230// aren't signaled. It should return an empty "RtpEncodingParameters" when
1231// configured to receive an unsignaled stream and no packets have been received
1232// yet, and start returning the SSRC once a packet has been received.
1233TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1234 ASSERT_TRUE(SetupChannel());
1235 // Call necessary methods to configure receiving a default stream as
1236 // soon as it arrives.
1237 cricket::AudioRecvParameters parameters;
1238 parameters.codecs.push_back(kIsacCodec);
1239 parameters.codecs.push_back(kPcmuCodec);
1240 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1241
1242 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1243 // stream. Should return nothing.
1244 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1245
1246 // Set a sink for an unsignaled stream.
1247 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1248 // Value of "0" means "unsignaled stream".
1249 channel_->SetRawAudioSink(0, std::move(fake_sink));
1250
1251 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1252 // in this method means "unsignaled stream".
1253 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1254 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1255 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1256
1257 // Receive PCMU packet (SSRC=1).
1258 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1259
1260 // The |ssrc| member should still be unset.
1261 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1262 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1263 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1264}
1265
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001266// Test that we apply codecs properly.
1267TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001268 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001269 cricket::AudioSendParameters parameters;
1270 parameters.codecs.push_back(kIsacCodec);
1271 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001272 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001274 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001275 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001276 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1277 EXPECT_EQ(96, send_codec_spec.payload_type);
1278 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1279 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1280 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001281 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001282 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283}
1284
ossu20a4b3f2017-04-27 02:08:52 -07001285// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1286// AudioSendStream.
1287TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001288 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 cricket::AudioSendParameters parameters;
1290 parameters.codecs.push_back(kIsacCodec);
1291 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001292 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001293 parameters.codecs[0].id = 96;
1294 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001295 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001296 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001297 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001298 // Calling SetSendCodec again with same codec which is already set.
1299 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001300 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001301 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001302}
1303
ossu20a4b3f2017-04-27 02:08:52 -07001304// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1305// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001306
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001307// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001308TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001309 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001310 cricket::AudioSendParameters parameters;
1311 parameters.codecs.push_back(kOpusCodec);
1312 parameters.codecs[0].bitrate = 0;
1313 parameters.codecs[0].clockrate = 50000;
1314 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001315}
1316
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001317// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001318TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001319 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001320 cricket::AudioSendParameters parameters;
1321 parameters.codecs.push_back(kOpusCodec);
1322 parameters.codecs[0].bitrate = 0;
1323 parameters.codecs[0].channels = 0;
1324 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001325}
1326
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001327// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001328TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001329 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001330 cricket::AudioSendParameters parameters;
1331 parameters.codecs.push_back(kOpusCodec);
1332 parameters.codecs[0].bitrate = 0;
1333 parameters.codecs[0].channels = 0;
1334 parameters.codecs[0].params["stereo"] = "1";
1335 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336}
1337
1338// Test that if channel is 1 for opus and there's no stereo, we fail.
1339TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001340 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001341 cricket::AudioSendParameters parameters;
1342 parameters.codecs.push_back(kOpusCodec);
1343 parameters.codecs[0].bitrate = 0;
1344 parameters.codecs[0].channels = 1;
1345 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346}
1347
1348// Test that if channel is 1 for opus and stereo=0, we fail.
1349TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001350 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 cricket::AudioSendParameters parameters;
1352 parameters.codecs.push_back(kOpusCodec);
1353 parameters.codecs[0].bitrate = 0;
1354 parameters.codecs[0].channels = 1;
1355 parameters.codecs[0].params["stereo"] = "0";
1356 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357}
1358
1359// Test that if channel is 1 for opus and stereo=1, we fail.
1360TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001361 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 cricket::AudioSendParameters parameters;
1363 parameters.codecs.push_back(kOpusCodec);
1364 parameters.codecs[0].bitrate = 0;
1365 parameters.codecs[0].channels = 1;
1366 parameters.codecs[0].params["stereo"] = "1";
1367 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368}
1369
ossu20a4b3f2017-04-27 02:08:52 -07001370// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001371TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001372 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 cricket::AudioSendParameters parameters;
1374 parameters.codecs.push_back(kOpusCodec);
1375 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001376 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001377 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001378}
1379
ossu20a4b3f2017-04-27 02:08:52 -07001380// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001382 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001383 cricket::AudioSendParameters parameters;
1384 parameters.codecs.push_back(kOpusCodec);
1385 parameters.codecs[0].bitrate = 0;
1386 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001387 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001388 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389}
1390
ossu20a4b3f2017-04-27 02:08:52 -07001391// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001392TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001393 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 cricket::AudioSendParameters parameters;
1395 parameters.codecs.push_back(kOpusCodec);
1396 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001397 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001399 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001400 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001401
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001403 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001404 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001405}
1406
ossu20a4b3f2017-04-27 02:08:52 -07001407// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001409 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 cricket::AudioSendParameters parameters;
1411 parameters.codecs.push_back(kOpusCodec);
1412 parameters.codecs[0].bitrate = 0;
1413 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001414 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001415 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416}
1417
ossu20a4b3f2017-04-27 02:08:52 -07001418// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001424 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001426 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001427 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001428
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001430 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001431 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001432}
1433
ossu20a4b3f2017-04-27 02:08:52 -07001434// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 cricket::AudioSendParameters parameters;
1438 parameters.codecs.push_back(kOpusCodec);
1439 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001440 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001441 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1442 EXPECT_EQ(111, spec.payload_type);
1443 EXPECT_EQ(96000, spec.target_bitrate_bps);
1444 EXPECT_EQ("opus", spec.format.name);
1445 EXPECT_EQ(2, spec.format.num_channels);
1446 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447}
1448
ossu20a4b3f2017-04-27 02:08:52 -07001449// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001450TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001451 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001452 cricket::AudioSendParameters parameters;
1453 parameters.codecs.push_back(kOpusCodec);
1454 parameters.codecs[0].bitrate = 30000;
1455 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001456 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001457 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458}
1459
ossu20a4b3f2017-04-27 02:08:52 -07001460// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001466 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001467 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468}
1469
ossu20a4b3f2017-04-27 02:08:52 -07001470// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001472 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 cricket::AudioSendParameters parameters;
1474 parameters.codecs.push_back(kOpusCodec);
1475 parameters.codecs[0].bitrate = 30000;
1476 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001478 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001479}
1480
stefan13f1a0a2016-11-30 07:22:58 -08001481TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1482 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1483 200000);
1484}
1485
1486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1487 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1488}
1489
1490TEST_F(WebRtcVoiceEngineTestFake,
1491 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1492 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1496 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1497}
1498
1499TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001500 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001501 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1502 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001503 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001504 SetSendParameters(send_parameters_);
1505 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1506 << "Setting max bitrate should keep previous min bitrate.";
1507 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1508 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001509 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001510}
1511
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001512// Test that we can enable NACK with opus as caller.
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001514 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001515 cricket::AudioSendParameters parameters;
1516 parameters.codecs.push_back(kOpusCodec);
1517 parameters.codecs[0].AddFeedbackParam(
1518 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1519 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001520 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001521 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001522 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001523}
1524
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001525// Test that we can enable NACK with opus as callee.
1526TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001527 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001528 cricket::AudioSendParameters parameters;
1529 parameters.codecs.push_back(kOpusCodec);
1530 parameters.codecs[0].AddFeedbackParam(
1531 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1532 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001533 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001534 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001535 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001536 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001537
1538 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001539 cricket::StreamParams::CreateLegacy(kSsrcX)));
1540 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001541}
1542
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543// Test that we can enable NACK on receive streams.
1544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001546 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001547 cricket::AudioSendParameters parameters;
1548 parameters.codecs.push_back(kOpusCodec);
1549 parameters.codecs[0].AddFeedbackParam(
1550 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1551 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1553 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001554 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1556 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001557}
1558
1559// Test that we can disable NACK.
1560TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001561 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001562 cricket::AudioSendParameters parameters;
1563 parameters.codecs.push_back(kOpusCodec);
1564 parameters.codecs[0].AddFeedbackParam(
1565 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1566 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001567 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001568 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001570 parameters.codecs.clear();
1571 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574}
1575
1576// Test that we can disable NACK on receive streams.
1577TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001578 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001579 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].AddFeedbackParam(
1583 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1584 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001585 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001586 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1587 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 parameters.codecs.clear();
1590 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001591 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001592 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1593 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001594}
1595
1596// Test that NACK is enabled on a new receive stream.
1597TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001598 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001599 cricket::AudioSendParameters parameters;
1600 parameters.codecs.push_back(kIsacCodec);
1601 parameters.codecs.push_back(kCn16000Codec);
1602 parameters.codecs[0].AddFeedbackParam(
1603 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1604 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001605 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001606 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
solenberg2100c0b2017-03-01 11:29:29 -08001608 EXPECT_TRUE(AddRecvStream(kSsrcY));
1609 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1610 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1611 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
stefanba4c0e42016-02-04 04:12:24 -08001614TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001615 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001616 cricket::AudioSendParameters send_parameters;
1617 send_parameters.codecs.push_back(kOpusCodec);
1618 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001619 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001620
1621 cricket::AudioRecvParameters recv_parameters;
1622 recv_parameters.codecs.push_back(kIsacCodec);
1623 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_TRUE(AddRecvStream(kSsrcX));
1625 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001626 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001627 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001628
ossudedfd282016-06-14 07:12:39 -07001629 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001630 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001631 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001632 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001633 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001634}
1635
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001636// Test that we can switch back and forth between Opus and ISAC with CN.
1637TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001638 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001639
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001640 cricket::AudioSendParameters opus_parameters;
1641 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001642 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001643 {
ossu20a4b3f2017-04-27 02:08:52 -07001644 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1645 EXPECT_EQ(111, spec.payload_type);
1646 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001647 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001648
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001649 cricket::AudioSendParameters isac_parameters;
1650 isac_parameters.codecs.push_back(kIsacCodec);
1651 isac_parameters.codecs.push_back(kCn16000Codec);
1652 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001654 {
ossu20a4b3f2017-04-27 02:08:52 -07001655 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1656 EXPECT_EQ(103, spec.payload_type);
1657 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001658 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001659
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001661 {
ossu20a4b3f2017-04-27 02:08:52 -07001662 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1663 EXPECT_EQ(111, spec.payload_type);
1664 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001665 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666}
1667
1668// Test that we handle various ways of specifying bitrate.
1669TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001670 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
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 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001683 {
ossu20a4b3f2017-04-27 02:08:52 -07001684 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1685 EXPECT_EQ(103, spec.payload_type);
1686 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1687 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001688 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
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(103, spec.payload_type);
1694 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1695 EXPECT_EQ(28000, 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] = kPcmuCodec; // bitrate == 64000
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_STRCASEEQ("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].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001708 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001709 {
ossu20a4b3f2017-04-27 02:08:52 -07001710 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1711 EXPECT_EQ(0, spec.payload_type);
1712 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1713 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001714 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001715
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001716 parameters.codecs[0] = kOpusCodec;
1717 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001718 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001719 {
ossu20a4b3f2017-04-27 02:08:52 -07001720 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1721 EXPECT_EQ(111, spec.payload_type);
1722 EXPECT_STREQ("opus", spec.format.name.c_str());
1723 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001724 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001725}
1726
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001727// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001728TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001729 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001730 cricket::AudioSendParameters parameters;
1731 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001732}
1733
1734// Test that we can set send codecs even with telephone-event codec as the first
1735// one on the list.
1736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001737 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001738 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001739 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 parameters.codecs.push_back(kIsacCodec);
1741 parameters.codecs.push_back(kPcmuCodec);
1742 parameters.codecs[0].id = 98; // DTMF
1743 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001744 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001745 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1746 EXPECT_EQ(96, spec.payload_type);
1747 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001748 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001749}
1750
solenberg31642aa2016-03-14 08:00:37 -07001751// Test that payload type range is limited for telephone-event codec.
1752TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001753 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001754 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001755 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001756 parameters.codecs.push_back(kIsacCodec);
1757 parameters.codecs[0].id = 0; // DTMF
1758 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001760 EXPECT_TRUE(channel_->CanInsertDtmf());
1761 parameters.codecs[0].id = 128; // DTMF
1762 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1763 EXPECT_FALSE(channel_->CanInsertDtmf());
1764 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001765 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001766 EXPECT_TRUE(channel_->CanInsertDtmf());
1767 parameters.codecs[0].id = -1; // DTMF
1768 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1769 EXPECT_FALSE(channel_->CanInsertDtmf());
1770}
1771
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001772// Test that we can set send codecs even with CN codec as the first
1773// one on the list.
1774TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001775 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001776 cricket::AudioSendParameters parameters;
1777 parameters.codecs.push_back(kCn16000Codec);
1778 parameters.codecs.push_back(kIsacCodec);
1779 parameters.codecs.push_back(kPcmuCodec);
1780 parameters.codecs[0].id = 98; // wideband CN
1781 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001783 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1784 EXPECT_EQ(96, send_codec_spec.payload_type);
1785 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001786 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787}
1788
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001789// Test that we set VAD and DTMF types correctly as caller.
1790TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001791 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001792 cricket::AudioSendParameters parameters;
1793 parameters.codecs.push_back(kIsacCodec);
1794 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001795 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 parameters.codecs.push_back(kCn16000Codec);
1797 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001798 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001799 parameters.codecs[0].id = 96;
1800 parameters.codecs[2].id = 97; // wideband CN
1801 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001803 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1804 EXPECT_EQ(96, send_codec_spec.payload_type);
1805 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1806 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001807 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001808 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809}
1810
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001811// Test that we set VAD and DTMF types correctly as callee.
1812TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001813 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 cricket::AudioSendParameters parameters;
1815 parameters.codecs.push_back(kIsacCodec);
1816 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001817 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs.push_back(kCn16000Codec);
1819 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001820 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001821 parameters.codecs[0].id = 96;
1822 parameters.codecs[2].id = 97; // wideband CN
1823 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001824 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001825 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001826 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001827
ossu20a4b3f2017-04-27 02:08:52 -07001828 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1829 EXPECT_EQ(96, send_codec_spec.payload_type);
1830 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1831 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001832 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001833 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001834}
1835
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001836// Test that we only apply VAD if we have a CN codec that matches the
1837// send codec clockrate.
1838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001841 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001842 parameters.codecs.push_back(kIsacCodec);
1843 parameters.codecs.push_back(kCn16000Codec);
1844 parameters.codecs[1].id = 97;
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("ISAC", send_codec_spec.format.name.c_str());
1849 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001850 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001851 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001853 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001854 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001855 {
ossu20a4b3f2017-04-27 02:08:52 -07001856 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1857 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001858 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001859 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001860 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001861 parameters.codecs[1] = kCn8000Codec;
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("PCMU", send_codec_spec.format.name.c_str());
1866 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001867 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001868 }
Brave Yao5225dd82015-03-26 07:39:19 +08001869 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001871 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001872 {
ossu20a4b3f2017-04-27 02:08:52 -07001873 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1874 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001875 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001877}
1878
1879// Test that we perform case-insensitive matching of codec names.
1880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001881 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters parameters;
1883 parameters.codecs.push_back(kIsacCodec);
1884 parameters.codecs.push_back(kPcmuCodec);
1885 parameters.codecs.push_back(kCn16000Codec);
1886 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001887 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 parameters.codecs[0].name = "iSaC";
1889 parameters.codecs[0].id = 96;
1890 parameters.codecs[2].id = 97; // wideband CN
1891 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001892 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001893 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1894 EXPECT_EQ(96, send_codec_spec.payload_type);
1895 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1896 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001897 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001898 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899}
1900
stefanba4c0e42016-02-04 04:12:24 -08001901class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1902 public:
1903 WebRtcVoiceEngineWithSendSideBweTest()
1904 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1905};
1906
1907TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1908 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001909 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001910 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001911 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1912 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1913 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001914 extension.id);
1915 return;
1916 }
1917 }
1918 FAIL() << "Transport sequence number extension not in header-extension list.";
1919}
1920
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001921// Test support for audio level header extension.
1922TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001923 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001924}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001925TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001926 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001927}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001928
solenbergd4adce42016-11-17 06:26:52 -08001929// Test support for transport sequence number header extension.
1930TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1931 TestSetSendRtpHeaderExtensions(
1932 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001933}
solenbergd4adce42016-11-17 06:26:52 -08001934TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1935 TestSetRecvRtpHeaderExtensions(
1936 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937}
1938
solenberg1ac56142015-10-13 03:58:19 -07001939// Test that we can create a channel and start sending on it.
1940TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001941 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001942 SetSendParameters(send_parameters_);
1943 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001944 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001945 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001946 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001947}
1948
1949// Test that a channel will send if and only if it has a source and is enabled
1950// for sending.
1951TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001952 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001953 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001954 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001955 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001956 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1957 SetAudioSend(kSsrcX, true, &fake_source_);
1958 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1959 SetAudioSend(kSsrcX, true, nullptr);
1960 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001961}
1962
solenberg94218532016-06-16 10:53:22 -07001963// Test that a channel is muted/unmuted.
1964TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1965 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001966 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001967 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1968 SetAudioSend(kSsrcX, true, nullptr);
1969 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1970 SetAudioSend(kSsrcX, false, nullptr);
1971 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001972}
1973
solenberg6d6e7c52016-04-13 09:07:30 -07001974// Test that SetSendParameters() does not alter a stream's send state.
1975TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1976 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001977 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001978
1979 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001980 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001981 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001982
1983 // Changing RTP header extensions will recreate the AudioSendStream.
1984 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001985 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001986 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001987 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001988
1989 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001990 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001991 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001992
1993 // Changing RTP header extensions will recreate the AudioSendStream.
1994 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001995 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001996 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001997}
1998
solenberg1ac56142015-10-13 03:58:19 -07001999// Test that we can create a channel and start playing out on it.
2000TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002001 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002002 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002003 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002004 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002005 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002006 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002007}
2008
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002009// Test that we can add and remove send streams.
2010TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2011 SetupForMultiSendStream();
2012
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002014 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015
solenbergc96df772015-10-21 13:01:53 -07002016 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002017 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002018 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002019 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002020 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002021 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002022 }
tfarina5237aaf2015-11-10 23:44:30 -08002023 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002024
solenbergc96df772015-10-21 13:01:53 -07002025 // Delete the send streams.
2026 for (uint32_t ssrc : kSsrcs4) {
2027 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002028 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002029 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002030 }
solenbergc96df772015-10-21 13:01:53 -07002031 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002032}
2033
2034// Test SetSendCodecs correctly configure the codecs in all send streams.
2035TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2036 SetupForMultiSendStream();
2037
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002039 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002041 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 }
2043
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002044 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002046 parameters.codecs.push_back(kIsacCodec);
2047 parameters.codecs.push_back(kCn16000Codec);
2048 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002049 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050
2051 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002052 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002053 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2054 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002055 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2056 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2057 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002058 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002059 }
2060
minyue7a973442016-10-20 03:27:12 -07002061 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002062 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002063 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002064 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002065 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2066 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002067 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2068 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002069 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070 }
2071}
2072
2073// Test we can SetSend on all send streams correctly.
2074TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2075 SetupForMultiSendStream();
2076
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002077 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002078 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002080 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002081 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002082 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 }
2084
2085 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002086 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002087 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002089 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002090 }
2091
2092 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002093 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002094 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002095 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002096 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002097 }
2098}
2099
2100// Test we can set the correct statistics on all send streams.
2101TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2102 SetupForMultiSendStream();
2103
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002104 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002105 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002106 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002107 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 }
solenberg85a04962015-10-27 03:35:21 -07002109
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002110 // Create a receive stream to check that none of the send streams end up in
2111 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002112 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002113
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002115 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002116 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002117 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118
solenberg85a04962015-10-27 03:35:21 -07002119 // Check stats for the added streams.
2120 {
2121 cricket::VoiceMediaInfo info;
2122 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123
solenberg85a04962015-10-27 03:35:21 -07002124 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002125 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002126 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002127 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002128 }
hbos1acfbd22016-11-17 23:43:29 -08002129 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002130
2131 // We have added one receive stream. We should see empty stats.
2132 EXPECT_EQ(info.receivers.size(), 1u);
2133 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002134 }
solenberg1ac56142015-10-13 03:58:19 -07002135
solenberg2100c0b2017-03-01 11:29:29 -08002136 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002137 {
2138 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002139 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002140 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002141 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002142 EXPECT_EQ(0u, info.receivers.size());
2143 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002144
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002145 // Deliver a new packet - a default receive stream should be created and we
2146 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002147 {
2148 cricket::VoiceMediaInfo info;
2149 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2150 SetAudioReceiveStreamStats();
2151 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002152 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002153 EXPECT_EQ(1u, info.receivers.size());
2154 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002155 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002156 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002157}
2158
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002159// Test that we can add and remove receive streams, and do proper send/playout.
2160// We can receive on multiple streams while sending one stream.
2161TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002162 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002163
solenberg1ac56142015-10-13 03:58:19 -07002164 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002165 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002166 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167
solenberg1ac56142015-10-13 03:58:19 -07002168 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002169 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002170 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002171 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002172
solenberg1ac56142015-10-13 03:58:19 -07002173 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002174 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002175
2176 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002177 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2178 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2179 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180
2181 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002182 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002183 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184
2185 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002186 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2188 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002189
aleloi84ef6152016-08-04 05:28:21 -07002190 // Restart playout and make sure recv streams are played out.
2191 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002192 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2193 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194
aleloi84ef6152016-08-04 05:28:21 -07002195 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002196 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2197 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198}
2199
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002200// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002201// and start sending on it.
2202TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002203 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002204 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002205 EXPECT_CALL(apm_gc_,
2206 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002207 SetSendParameters(send_parameters_);
2208 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002209 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002210 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002211 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002212}
2213
wu@webrtc.org97077a32013-10-25 21:18:33 +00002214TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002215 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002216 EXPECT_CALL(adm_,
2217 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002218 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2219 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002220 send_parameters_.options.tx_agc_target_dbov = 3;
2221 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2222 send_parameters_.options.tx_agc_limiter = true;
2223 send_parameters_.options.auto_gain_control = true;
solenberg76377c52017-02-21 00:54:31 -08002224 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2225 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2226 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002227 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002228
2229 // Check interaction with adjust_agc_delta. Both should be respected, for
2230 // backwards compatibility.
Oskar Sundbom78807582017-11-16 11:09:55 +01002231 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002232 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002233 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002234}
2235
minyue6b825df2016-10-31 04:08:32 -07002236TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2237 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002238 send_parameters_.options.audio_network_adaptor = true;
2239 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002240 SetSendParameters(send_parameters_);
2241 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002242 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002243}
2244
2245TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2246 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002247 send_parameters_.options.audio_network_adaptor = true;
2248 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002249 SetSendParameters(send_parameters_);
2250 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002251 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002252 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002253 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002254 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002255 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002256}
2257
2258TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2259 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002260 send_parameters_.options.audio_network_adaptor = true;
2261 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002262 SetSendParameters(send_parameters_);
2263 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002264 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002265 const int initial_num = call_.GetNumCreatedSendStreams();
2266 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002267 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002268 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2269 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002270 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002271 // AudioSendStream not expected to be recreated.
2272 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2273 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002274 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275}
2276
michaelt6672b262017-01-11 10:17:59 -08002277class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2278 : public WebRtcVoiceEngineTestFake {
2279 public:
2280 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2281 : WebRtcVoiceEngineTestFake(
2282 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2283 "Enabled/") {}
2284};
2285
2286TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2287 EXPECT_TRUE(SetupSendStream());
2288 cricket::AudioSendParameters parameters;
2289 parameters.codecs.push_back(kOpusCodec);
2290 SetSendParameters(parameters);
2291 const int initial_num = call_.GetNumCreatedSendStreams();
2292 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2293
2294 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2295 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002296 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2297 constexpr int kMinOverheadBps =
2298 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002299
2300 constexpr int kOpusMinBitrateBps = 6000;
2301 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002302 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002303 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002304 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002305 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002306
Oskar Sundbom78807582017-11-16 11:09:55 +01002307 parameters.options.audio_network_adaptor = true;
2308 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002309 SetSendParameters(parameters);
2310
ossu11bfc532017-02-16 05:37:06 -08002311 constexpr int kMinOverheadWithAnaBps =
2312 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002313
2314 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002315 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002316
minyuececec102017-03-27 13:04:25 -07002317 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002318 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002319}
2320
minyuececec102017-03-27 13:04:25 -07002321// This test is similar to
2322// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2323// additional field trial.
2324TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2325 SetRtpSendParameterUpdatesMaxBitrate) {
2326 EXPECT_TRUE(SetupSendStream());
2327 cricket::AudioSendParameters send_parameters;
2328 send_parameters.codecs.push_back(kOpusCodec);
2329 SetSendParameters(send_parameters);
2330
2331 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2332 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2333 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2334
2335 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002336 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002337 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2338
2339 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2340#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2341 constexpr int kMinOverhead = 3333;
2342#else
2343 constexpr int kMinOverhead = 6666;
2344#endif
2345 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2346}
2347
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002348// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002349// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002350TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002351 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002352 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002353}
2354
2355TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2356 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002357 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002358 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002359 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002360 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002361 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002362 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002363 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002364
solenberg85a04962015-10-27 03:35:21 -07002365 // Check stats for the added streams.
2366 {
2367 cricket::VoiceMediaInfo info;
2368 EXPECT_EQ(true, channel_->GetStats(&info));
2369
2370 // We have added one send stream. We should see the stats we've set.
2371 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002372 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002373 // We have added one receive stream. We should see empty stats.
2374 EXPECT_EQ(info.receivers.size(), 1u);
2375 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2376 }
solenberg1ac56142015-10-13 03:58:19 -07002377
solenberg566ef242015-11-06 15:34:49 -08002378 // Start sending - this affects some reported stats.
2379 {
2380 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002381 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002382 EXPECT_EQ(true, channel_->GetStats(&info));
2383 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002384 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002385 }
2386
solenberg2100c0b2017-03-01 11:29:29 -08002387 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002388 {
2389 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002390 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002391 EXPECT_EQ(true, channel_->GetStats(&info));
2392 EXPECT_EQ(1u, info.senders.size());
2393 EXPECT_EQ(0u, info.receivers.size());
2394 }
solenberg1ac56142015-10-13 03:58:19 -07002395
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002396 // Deliver a new packet - a default receive stream should be created and we
2397 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002398 {
2399 cricket::VoiceMediaInfo info;
2400 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2401 SetAudioReceiveStreamStats();
2402 EXPECT_EQ(true, channel_->GetStats(&info));
2403 EXPECT_EQ(1u, info.senders.size());
2404 EXPECT_EQ(1u, info.receivers.size());
2405 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002406 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002407 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002408}
2409
2410// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002411// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002412TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002413 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002414 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2415 EXPECT_TRUE(AddRecvStream(kSsrcY));
2416 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417}
2418
2419// Test that the local SSRC is the same on sending and receiving channels if the
2420// receive channel is created before the send channel.
2421TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002422 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002423 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002424 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002425 cricket::StreamParams::CreateLegacy(kSsrcX)));
2426 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2427 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428}
2429
2430// Test that we can properly receive packets.
2431TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002433 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002435
2436 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2437 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438}
2439
2440// Test that we can properly receive packets on multiple streams.
2441TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002442 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002443 const uint32_t ssrc1 = 1;
2444 const uint32_t ssrc2 = 2;
2445 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002446 EXPECT_TRUE(AddRecvStream(ssrc1));
2447 EXPECT_TRUE(AddRecvStream(ssrc2));
2448 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002449 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002450 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002451 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002453 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 }
mflodman3d7db262016-04-29 00:57:13 -07002455
2456 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2457 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2458 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2459
2460 EXPECT_EQ(s1.received_packets(), 0);
2461 EXPECT_EQ(s2.received_packets(), 0);
2462 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002463
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002465 EXPECT_EQ(s1.received_packets(), 0);
2466 EXPECT_EQ(s2.received_packets(), 0);
2467 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002468
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002470 EXPECT_EQ(s1.received_packets(), 1);
2471 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2472 EXPECT_EQ(s2.received_packets(), 0);
2473 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002474
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002475 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002476 EXPECT_EQ(s1.received_packets(), 1);
2477 EXPECT_EQ(s2.received_packets(), 1);
2478 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2479 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002480
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002482 EXPECT_EQ(s1.received_packets(), 1);
2483 EXPECT_EQ(s2.received_packets(), 1);
2484 EXPECT_EQ(s3.received_packets(), 1);
2485 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002486
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2488 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2489 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490}
2491
solenberg2100c0b2017-03-01 11:29:29 -08002492// Test that receiving on an unsignaled stream works (a stream is created).
2493TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002494 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002495 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2496
solenberg7e63ef02015-11-20 00:19:43 -08002497 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002498
2499 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002500 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2501 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002502}
2503
solenberg2100c0b2017-03-01 11:29:29 -08002504// Test that receiving N unsignaled stream works (streams will be created), and
2505// that packets are forwarded to them all.
2506TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002507 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002508 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002509 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2510
solenberg2100c0b2017-03-01 11:29:29 -08002511 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002512 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002513 rtc::SetBE32(&packet[8], ssrc);
2514 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002515
solenberg2100c0b2017-03-01 11:29:29 -08002516 // Verify we have one new stream for each loop iteration.
2517 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002518 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2519 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002520 }
mflodman3d7db262016-04-29 00:57:13 -07002521
solenberg2100c0b2017-03-01 11:29:29 -08002522 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002523 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002524 rtc::SetBE32(&packet[8], ssrc);
2525 DeliverPacket(packet, sizeof(packet));
2526
solenbergebb349d2017-03-13 05:46:15 -07002527 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002528 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2529 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2530 }
2531
2532 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2533 constexpr uint32_t kAnotherSsrc = 667;
2534 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002535 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002536
2537 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002538 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002539 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002540 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002541 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2542 EXPECT_EQ(2, streams[i]->received_packets());
2543 }
2544 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2545 EXPECT_EQ(1, streams[i]->received_packets());
2546 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002547 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002548}
2549
solenberg2100c0b2017-03-01 11:29:29 -08002550// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002551// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002552TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002553 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002554 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002555 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2556
2557 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002558 const uint32_t signaled_ssrc = 1;
2559 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002560 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002561 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002562 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2563 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002564 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002565
2566 // Note that the first unknown SSRC cannot be 0, because we only support
2567 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002568 const uint32_t unsignaled_ssrc = 7011;
2569 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002570 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002571 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2572 packet, sizeof(packet)));
2573 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2574
2575 DeliverPacket(packet, sizeof(packet));
2576 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2577
2578 rtc::SetBE32(&packet[8], signaled_ssrc);
2579 DeliverPacket(packet, sizeof(packet));
2580 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2581 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002582}
2583
solenberg4904fb62017-02-17 12:01:14 -08002584// Two tests to verify that adding a receive stream with the same SSRC as a
2585// previously added unsignaled stream will only recreate underlying stream
2586// objects if the stream parameters have changed.
2587TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2588 EXPECT_TRUE(SetupChannel());
2589
2590 // Spawn unsignaled stream with SSRC=1.
2591 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2592 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2593 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2594 sizeof(kPcmuFrame)));
2595
2596 // Verify that the underlying stream object in Call is not recreated when a
2597 // stream with SSRC=1 is added.
2598 const auto& streams = call_.GetAudioReceiveStreams();
2599 EXPECT_EQ(1, streams.size());
2600 int audio_receive_stream_id = streams.front()->id();
2601 EXPECT_TRUE(AddRecvStream(1));
2602 EXPECT_EQ(1, streams.size());
2603 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2604}
2605
2606TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2607 EXPECT_TRUE(SetupChannel());
2608
2609 // Spawn unsignaled stream with SSRC=1.
2610 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2611 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2612 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2613 sizeof(kPcmuFrame)));
2614
2615 // Verify that the underlying stream object in Call *is* recreated when a
2616 // stream with SSRC=1 is added, and which has changed stream parameters.
2617 const auto& streams = call_.GetAudioReceiveStreams();
2618 EXPECT_EQ(1, streams.size());
2619 int audio_receive_stream_id = streams.front()->id();
2620 cricket::StreamParams stream_params;
2621 stream_params.ssrcs.push_back(1);
2622 stream_params.sync_label = "sync_label";
2623 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2624 EXPECT_EQ(1, streams.size());
2625 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2626}
2627
solenberg0a617e22015-10-20 15:49:38 -07002628// Test that we properly handle failures to add a receive stream.
2629TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002630 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002632 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002633}
2634
solenberg0a617e22015-10-20 15:49:38 -07002635// Test that we properly handle failures to add a send stream.
2636TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002637 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002638 voe_.set_fail_create_channel(true);
2639 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2640}
2641
solenberg1ac56142015-10-13 03:58:19 -07002642// Test that AddRecvStream creates new stream.
2643TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002644 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002645 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002646 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002647 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648}
2649
2650// Test that after adding a recv stream, we do not decode more codecs than
2651// those previously passed into SetRecvCodecs.
2652TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002653 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002654 cricket::AudioRecvParameters parameters;
2655 parameters.codecs.push_back(kIsacCodec);
2656 parameters.codecs.push_back(kPcmuCodec);
2657 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002658 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002659 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2660 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2661 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662}
2663
2664// Test that we properly clean up any streams that were added, even if
2665// not explicitly removed.
2666TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002667 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002668 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002669 EXPECT_TRUE(AddRecvStream(1));
2670 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002671 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2672 delete channel_;
2673 channel_ = NULL;
2674 EXPECT_EQ(0, voe_.GetNumChannels());
2675}
2676
wu@webrtc.org78187522013-10-07 23:32:02 +00002677TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002678 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002679 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002680}
2681
2682TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002683 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002684 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002685 // Manually delete channel to simulate a failure.
2686 int channel = voe_.GetLastChannel();
2687 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2688 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002689 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002690 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002691 EXPECT_NE(channel, new_channel);
2692 // The last created channel is deleted too.
2693 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002694}
2695
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002696// Test the InsertDtmf on default send stream as caller.
2697TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002698 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699}
2700
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002701// Test the InsertDtmf on default send stream as callee
2702TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002703 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002704}
2705
2706// Test the InsertDtmf on specified send stream as caller.
2707TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002708 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002709}
2710
2711// Test the InsertDtmf on specified send stream as callee.
2712TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002713 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714}
2715
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002717 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002718 EXPECT_CALL(adm_,
2719 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2720 EXPECT_CALL(adm_,
2721 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2722 EXPECT_CALL(adm_,
2723 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002724
solenberg246b8172015-12-08 09:50:23 -08002725 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2726 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727
solenberg246b8172015-12-08 09:50:23 -08002728 // Nothing set in AudioOptions, so everything should be as default.
2729 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002730 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002731 EXPECT_TRUE(IsHighPassFilterEnabled());
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
2735 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002736 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2737 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002738 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002739 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740
2741 // Turn echo cancellation back on, with settings, and make sure
2742 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002743 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2744 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002745 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002746 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002748 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2749 // control.
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));
Oskar Sundbom78807582017-11-16 11:09:55 +01002752 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002753 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002754
2755 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002756 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2757 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002758 send_parameters_.options.delay_agnostic_aec = false;
2759 send_parameters_.options.extended_filter_aec = false;
2760 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002761 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002762
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002763 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002764 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2765 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002766 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002767 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002768
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002770 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2771 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002774 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002775 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776
2777 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002778 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2780 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2781 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002782 send_parameters_.options.auto_gain_control = true;
2783 send_parameters_.options.adjust_agc_delta = rtc::nullopt;
solenberg059fb442016-10-26 05:12:24 -07002784 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002785
2786 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002787 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2789 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2792 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2793 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002794 send_parameters_.options.noise_suppression = false;
2795 send_parameters_.options.highpass_filter = false;
2796 send_parameters_.options.typing_detection = false;
2797 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002798 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002799 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002800
solenberg1ac56142015-10-13 03:58:19 -07002801 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002802 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2803 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2804 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2805 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2806 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2807 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2808 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002809 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002810}
2811
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002812TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002813 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002814 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002815 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002816 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002817 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002818 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002819 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002820 EXPECT_CALL(adm_,
2821 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2822 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2823 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002824 webrtc::AudioProcessing::Config apm_config;
2825 EXPECT_CALL(*apm_, GetConfig())
2826 .Times(10)
2827 .WillRepeatedly(ReturnPointee(&apm_config));
2828 EXPECT_CALL(*apm_, ApplyConfig(_))
2829 .Times(10)
2830 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002831 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002832
kwiberg686a8ef2016-02-26 03:00:35 -08002833 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002834 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002835 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002836 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002837 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002838 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002839
2840 // Have to add a stream to make SetSend work.
2841 cricket::StreamParams stream1;
2842 stream1.ssrcs.push_back(1);
2843 channel1->AddSendStream(stream1);
2844 cricket::StreamParams stream2;
2845 stream2.ssrcs.push_back(2);
2846 channel2->AddSendStream(stream2);
2847
2848 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002849 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002850 parameters_options_all.options.echo_cancellation = true;
2851 parameters_options_all.options.auto_gain_control = true;
2852 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002853 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2854 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2855 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2856 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2857 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002858 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002859 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002860 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002861 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002862
2863 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002864 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002865 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002866 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2867 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2868 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002871 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002872 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002873 expected_options.echo_cancellation = true;
2874 expected_options.auto_gain_control = true;
2875 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002876 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877
2878 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002880 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002881 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2882 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2883 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002886 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002887 expected_options.echo_cancellation = true;
2888 expected_options.auto_gain_control = false;
2889 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002890 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002891
solenberg76377c52017-02-21 00:54:31 -08002892 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002897 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002898
solenberg76377c52017-02-21 00:54:31 -08002899 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2902 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2903 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002904 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002905
solenberg76377c52017-02-21 00:54:31 -08002906 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2908 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2909 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2910 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002911 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002914 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2915 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002916 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2917 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002918 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2920 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2921 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2922 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002923 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002924 expected_options.echo_cancellation = true;
2925 expected_options.auto_gain_control = false;
2926 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002927 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928}
2929
wu@webrtc.orgde305012013-10-31 15:40:38 +00002930// This test verifies DSCP settings are properly applied on voice media channel.
2931TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002932 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002933 cricket::FakeNetworkInterface network_interface;
2934 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002935 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002936
peahb1c9d1d2017-07-25 15:45:24 -07002937 webrtc::AudioProcessing::Config apm_config;
2938 EXPECT_CALL(*apm_, GetConfig())
2939 .Times(3)
2940 .WillRepeatedly(ReturnPointee(&apm_config));
2941 EXPECT_CALL(*apm_, ApplyConfig(_))
2942 .Times(3)
2943 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002944 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002945
solenbergbc37fc82016-04-04 09:54:44 -07002946 channel.reset(
2947 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002948 channel->SetInterface(&network_interface);
2949 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2950 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2951
2952 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002953 channel.reset(
2954 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002955 channel->SetInterface(&network_interface);
2956 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2957
2958 // Verify that setting the option to false resets the
2959 // DiffServCodePoint.
2960 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002961 channel.reset(
2962 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002963 channel->SetInterface(&network_interface);
2964 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2965 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2966
2967 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002968}
2969
solenberg1ac56142015-10-13 03:58:19 -07002970TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002971 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 cricket::WebRtcVoiceMediaChannel* media_channel =
2973 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002974 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002975 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002976 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002977 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2978 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2979 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002980 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002981 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002982}
2983
solenberg1ac56142015-10-13 03:58:19 -07002984TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002985 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002987 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2988 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2989 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002990 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002991 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002992 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2993 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002994 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002995 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002996 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002997 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998}
2999
solenberg4bac9c52015-10-09 02:32:53 -07003000TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003001 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003004 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003005 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003006 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3007 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3008 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003009}
3010
solenberg2100c0b2017-03-01 11:29:29 -08003011TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003012 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003013
3014 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003015 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3017
3018 // Should remember the volume "2" which will be set on new unsignaled streams,
3019 // and also set the gain to 2 on existing unsignaled streams.
3020 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3021 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3022
3023 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3024 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3025 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3026 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3027 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3028 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3029
3030 // Setting gain with SSRC=0 should affect all unsignaled streams.
3031 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003032 if (kMaxUnsignaledRecvStreams > 1) {
3033 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3034 }
solenberg2100c0b2017-03-01 11:29:29 -08003035 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3036
3037 // Setting gain on an individual stream affects only that.
3038 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003039 if (kMaxUnsignaledRecvStreams > 1) {
3040 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3041 }
solenberg2100c0b2017-03-01 11:29:29 -08003042 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003043}
3044
pbos8fc7fa72015-07-15 08:02:58 -07003045TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003046 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003047 const std::string kSyncLabel = "AvSyncLabel";
3048
solenbergff976312016-03-30 23:28:51 -07003049 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003050 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3051 sp.sync_label = kSyncLabel;
3052 // Creating two channels to make sure that sync label is set properly for both
3053 // the default voice channel and following ones.
3054 EXPECT_TRUE(channel_->AddRecvStream(sp));
3055 sp.ssrcs[0] += 1;
3056 EXPECT_TRUE(channel_->AddRecvStream(sp));
3057
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003058 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003059 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003060 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003061 << "SyncGroup should be set based on sync_label";
3062 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003063 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003064 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003065}
3066
solenberg3a941542015-11-16 07:34:50 -08003067// TODO(solenberg): Remove, once recv streams are configured through Call.
3068// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003069TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003070 // Test that setting the header extensions results in the expected state
3071 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003072 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003073 ssrcs.push_back(223);
3074 ssrcs.push_back(224);
3075
solenbergff976312016-03-30 23:28:51 -07003076 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003077 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003078 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003079 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003080 cricket::StreamParams::CreateLegacy(ssrc)));
3081 }
3082
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003083 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003084 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003085 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003086 EXPECT_NE(nullptr, s);
3087 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3088 }
3089
3090 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003091 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003092 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003093 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003094 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003095 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003096 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003097 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003098 EXPECT_NE(nullptr, s);
3099 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003100 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3101 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102 for (const auto& s_ext : s_exts) {
3103 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003104 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 }
3106 }
3107 }
3108 }
3109
3110 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003111 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003112 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003113 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003114 EXPECT_NE(nullptr, s);
3115 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3116 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003117}
3118
3119TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3120 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003121 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003122 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003123 static const unsigned char kRtcp[] = {
3124 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3125 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3128 };
jbaucheec21bd2016-03-20 06:15:43 -07003129 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003130
solenbergff976312016-03-30 23:28:51 -07003131 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003132 cricket::WebRtcVoiceMediaChannel* media_channel =
3133 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003134 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003135 EXPECT_TRUE(media_channel->AddRecvStream(
3136 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3137
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003138 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003139 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003140 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003141 EXPECT_EQ(0, s->received_packets());
3142 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3143 EXPECT_EQ(1, s->received_packets());
3144 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3145 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146}
Minyue2013aec2015-05-13 14:14:42 +02003147
solenberg0a617e22015-10-20 15:49:38 -07003148// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003149// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003150TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003151 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003152 EXPECT_TRUE(AddRecvStream(kSsrcY));
3153 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003154 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003155 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3156 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3157 EXPECT_TRUE(AddRecvStream(kSsrcW));
3158 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003159}
3160
solenberg7602aab2016-11-14 11:30:07 -08003161TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3162 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003163 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003164 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003165 cricket::StreamParams::CreateLegacy(kSsrcY)));
3166 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3167 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3168 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003169 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003170 cricket::StreamParams::CreateLegacy(kSsrcW)));
3171 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3172 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003173}
stefan658910c2015-09-03 05:48:32 -07003174
deadbeef884f5852016-01-15 09:20:04 -08003175TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003177 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3178 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003179
3180 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003181 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3182 EXPECT_TRUE(AddRecvStream(kSsrcX));
3183 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003184
3185 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003186 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3187 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003188
3189 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003190 channel_->SetRawAudioSink(kSsrcX, nullptr);
3191 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003192}
3193
solenberg2100c0b2017-03-01 11:29:29 -08003194TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003195 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003196 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3197 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003198 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3199 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003200
3201 // Should be able to set a default sink even when no stream exists.
3202 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3203
solenberg2100c0b2017-03-01 11:29:29 -08003204 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3205 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003206 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003207 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003208
3209 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003210 channel_->SetRawAudioSink(kSsrc0, nullptr);
3211 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003212
3213 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003214 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3215 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003216
3217 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003218 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003219 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003220 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3221
3222 // Spawn another unsignaled stream - it should be assigned the default sink
3223 // and the previous unsignaled stream should lose it.
3224 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3225 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3226 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3227 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003228 if (kMaxUnsignaledRecvStreams > 1) {
3229 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3230 }
solenberg2100c0b2017-03-01 11:29:29 -08003231 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3232
3233 // Reset the default sink - the second unsignaled stream should lose it.
3234 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003235 if (kMaxUnsignaledRecvStreams > 1) {
3236 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3237 }
solenberg2100c0b2017-03-01 11:29:29 -08003238 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3239
3240 // Try setting the default sink while two streams exists.
3241 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003242 if (kMaxUnsignaledRecvStreams > 1) {
3243 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3244 }
solenberg2100c0b2017-03-01 11:29:29 -08003245 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3246
3247 // Try setting the sink for the first unsignaled stream using its known SSRC.
3248 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003249 if (kMaxUnsignaledRecvStreams > 1) {
3250 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3251 }
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003253 if (kMaxUnsignaledRecvStreams > 1) {
3254 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3255 }
deadbeef884f5852016-01-15 09:20:04 -08003256}
3257
skvlad7a43d252016-03-22 15:32:27 -07003258// Test that, just like the video channel, the voice channel communicates the
3259// network state to the call.
3260TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003261 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003262
3263 EXPECT_EQ(webrtc::kNetworkUp,
3264 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3265 EXPECT_EQ(webrtc::kNetworkUp,
3266 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3267
3268 channel_->OnReadyToSend(false);
3269 EXPECT_EQ(webrtc::kNetworkDown,
3270 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3271 EXPECT_EQ(webrtc::kNetworkUp,
3272 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3273
3274 channel_->OnReadyToSend(true);
3275 EXPECT_EQ(webrtc::kNetworkUp,
3276 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3277 EXPECT_EQ(webrtc::kNetworkUp,
3278 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3279}
3280
aleloi18e0b672016-10-04 02:45:47 -07003281// Test that playout is still started after changing parameters
3282TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3283 SetupRecvStream();
3284 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003285 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003286
3287 // Changing RTP header extensions will recreate the AudioReceiveStream.
3288 cricket::AudioRecvParameters parameters;
3289 parameters.extensions.push_back(
3290 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3291 channel_->SetRecvParameters(parameters);
3292
solenberg2100c0b2017-03-01 11:29:29 -08003293 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003294}
3295
stefan658910c2015-09-03 05:48:32 -07003296// Tests that the library initializes and shuts down properly.
3297TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003298 // If the VoiceEngine wants to gather available codecs early, that's fine but
3299 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003300 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003301 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3302 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003303 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003304 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003305 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003306 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003307 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003308 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003309 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003310 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3311 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003312 EXPECT_TRUE(channel != nullptr);
3313 delete channel;
solenbergff976312016-03-30 23:28:51 -07003314}
stefan658910c2015-09-03 05:48:32 -07003315
solenbergff976312016-03-30 23:28:51 -07003316// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003317TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3318 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003319 EXPECT_CALL(adm, AddRef()).Times(3);
3320 EXPECT_CALL(adm, Release())
3321 .Times(3)
3322 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003323 {
peaha9cc40b2017-06-29 08:32:09 -07003324 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3325 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003326 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003327 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003328 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003329 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003330 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003331 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003332 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003333 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3334 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3335 EXPECT_TRUE(channel != nullptr);
3336 delete channel;
3337 }
stefan658910c2015-09-03 05:48:32 -07003338}
3339
ossu20a4b3f2017-04-27 02:08:52 -07003340// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3341TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003342 // TODO(ossu): Why are the payload types of codecs with non-static payload
3343 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003344 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003345 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3346 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003347 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003348 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003349 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003350 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003351 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003352 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3353 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3354 (clockrate == 0 || codec.clockrate == clockrate);
3355 };
3356 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003357 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003358 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003359 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003360 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003361 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003362 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003363 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003364 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003365 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003366 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003367 EXPECT_EQ(126, codec.id);
3368 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3369 // Remove these checks once both send and receive side assigns payload types
3370 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003373 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003374 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003375 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003376 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003377 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003378 EXPECT_EQ(111, codec.id);
3379 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3380 EXPECT_EQ("10", codec.params.find("minptime")->second);
3381 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3382 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003383 }
3384 }
stefan658910c2015-09-03 05:48:32 -07003385}
3386
3387// Tests that VoE supports at least 32 channels
3388TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003389 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003390 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3391 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003392 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003393 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003394 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003395 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003396 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003397 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003398 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003399
3400 cricket::VoiceMediaChannel* channels[32];
3401 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003402 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003403 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3404 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003405 if (!channel)
3406 break;
stefan658910c2015-09-03 05:48:32 -07003407 channels[num_channels++] = channel;
3408 }
3409
tfarina5237aaf2015-11-10 23:44:30 -08003410 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003411 EXPECT_EQ(expected, num_channels);
3412
3413 while (num_channels > 0) {
3414 delete channels[--num_channels];
3415 }
stefan658910c2015-09-03 05:48:32 -07003416}
3417
3418// Test that we set our preferred codecs properly.
3419TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003420 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3421 // - Check that our builtin codecs are usable by Channel.
3422 // - The codecs provided by the engine is usable by Channel.
3423 // It does not check that the codecs in the RecvParameters are actually
3424 // what we sent in - though it's probably reasonable to expect so, if
3425 // SetRecvParameters returns true.
3426 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003427 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003428 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3429 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003430 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003431 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003432 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003433 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003434 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003435 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003436 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003437 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3438 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003439 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003440 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003441 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003442}
ossu9def8002017-02-09 05:14:32 -08003443
3444TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3445 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003446 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3447 {48000, 2, 16000, 10000, 20000}};
3448 spec1.info.allow_comfort_noise = false;
3449 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003450 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003451 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3452 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003453 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003454 specs.push_back(webrtc::AudioCodecSpec{
3455 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3456 {16000, 1, 13300}});
3457 specs.push_back(
3458 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3459 specs.push_back(
3460 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003461
ossueb1fde42017-05-02 06:46:30 -07003462 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3463 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3464 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003465 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003466 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003467 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003468 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003469
peaha9cc40b2017-06-29 08:32:09 -07003470 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3471 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003472 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003473 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003474 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003475 auto codecs = engine.recv_codecs();
3476 EXPECT_EQ(11, codecs.size());
3477
3478 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3479 // check the actual values safely, to provide better test results.
3480 auto get_codec =
3481 [&codecs](size_t index) -> const cricket::AudioCodec& {
3482 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3483 if (codecs.size() > index)
3484 return codecs[index];
3485 return missing_codec;
3486 };
3487
3488 // Ensure the general codecs are generated first and in order.
3489 for (size_t i = 0; i != specs.size(); ++i) {
3490 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3491 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3492 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3493 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3494 }
3495
3496 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003497 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003498 auto find_codec =
3499 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3500 for (size_t i = 0; i != codecs.size(); ++i) {
3501 const cricket::AudioCodec& codec = codecs[i];
3502 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3503 codec.clockrate == format.clockrate_hz &&
3504 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003505 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003506 }
3507 }
3508 return -1;
3509 };
3510
3511 // Ensure all supplementary codecs are generated last. Their internal ordering
3512 // is not important.
3513 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3514 const int num_specs = static_cast<int>(specs.size());
3515 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3516 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3517 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3518 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3519 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3520 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3521 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3522}