blob: e370612cb3827a67e9b8fbc2020ff5722db13d53 [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
deadbeefe702b302017-02-04 12:09:01 -0800373 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700374 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700375 }
376
solenberg059fb442016-10-26 05:12:24 -0700377 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700378 cricket::AudioSendParameters send_parameters;
379 send_parameters.codecs.push_back(codec);
380 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700381 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700382 }
383
ossu20a4b3f2017-04-27 02:08:52 -0700384 void CheckSendCodecBitrate(int32_t ssrc,
385 const char expected_name[],
386 int expected_bitrate) {
387 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
388 EXPECT_EQ(expected_name, spec->format.name);
389 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700390 }
391
ossu20a4b3f2017-04-27 02:08:52 -0700392 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
393 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700394 }
395
minyue6b825df2016-10-31 04:08:32 -0700396 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
397 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
398 }
399
skvlade0d46372016-04-07 22:59:22 -0700400 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
401 int global_max,
402 int stream_max,
403 bool expected_result,
404 int expected_codec_bitrate) {
405 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800406 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700407
408 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700409 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800410 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700411
412 // Verify that reading back the parameters gives results
413 // consistent with the Set() result.
414 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800415 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700416 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
417 EXPECT_EQ(expected_result ? stream_max : -1,
418 resulting_parameters.encodings[0].max_bitrate_bps);
419
420 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800421 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700422 }
423
stefan13f1a0a2016-11-30 07:22:58 -0800424 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
425 int expected_min_bitrate_bps,
426 const char* start_bitrate_kbps,
427 int expected_start_bitrate_bps,
428 const char* max_bitrate_kbps,
429 int expected_max_bitrate_bps) {
430 EXPECT_TRUE(SetupSendStream());
431 auto& codecs = send_parameters_.codecs;
432 codecs.clear();
433 codecs.push_back(kOpusCodec);
434 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
436 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
437 SetSendParameters(send_parameters_);
438
439 EXPECT_EQ(expected_min_bitrate_bps,
440 call_.GetConfig().bitrate_config.min_bitrate_bps);
441 EXPECT_EQ(expected_start_bitrate_bps,
442 call_.GetConfig().bitrate_config.start_bitrate_bps);
443 EXPECT_EQ(expected_max_bitrate_bps,
444 call_.GetConfig().bitrate_config.max_bitrate_bps);
445 }
446
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000447 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700448 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000449
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000450 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800451 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
453 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700454 send_parameters_.extensions.push_back(
455 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000458
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700461 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800462 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000463
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000464 // Ensure extension is set properly.
465 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700466 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700467 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800468 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
469 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
470 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000471
solenberg7add0582015-11-20 09:59:34 -0800472 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800474 cricket::StreamParams::CreateLegacy(kSsrcY)));
475 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
476 call_.GetAudioSendStream(kSsrcY));
477 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
478 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
479 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000480
481 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200482 send_parameters_.codecs.push_back(kPcmuCodec);
483 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700484 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
486 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000487 }
488
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000489 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700490 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800493 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
495 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700496 recv_parameters_.extensions.push_back(
497 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800498 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800499 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000500
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000501 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800502 recv_parameters_.extensions.clear();
503 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800504 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000505
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000506 // Ensure extension is set properly.
507 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700508 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800509 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800510 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
511 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
512 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000513
solenberg7add0582015-11-20 09:59:34 -0800514 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_TRUE(AddRecvStream(kSsrcY));
516 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
517 call_.GetAudioReceiveStream(kSsrcY));
518 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
519 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
520 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000521
522 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800523 recv_parameters_.extensions.clear();
524 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
526 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000527 }
528
solenberg85a04962015-10-27 03:35:21 -0700529 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
530 webrtc::AudioSendStream::Stats stats;
531 stats.local_ssrc = 12;
532 stats.bytes_sent = 345;
533 stats.packets_sent = 678;
534 stats.packets_lost = 9012;
535 stats.fraction_lost = 34.56f;
536 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800537 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700538 stats.ext_seqnum = 789;
539 stats.jitter_ms = 12;
540 stats.rtt_ms = 345;
541 stats.audio_level = 678;
542 stats.aec_quality_min = 9.01f;
543 stats.echo_delay_median_ms = 234;
544 stats.echo_delay_std_ms = 567;
545 stats.echo_return_loss = 890;
546 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700547 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800548 stats.residual_echo_likelihood_recent_max = 0.6f;
ivoce1198e02017-09-08 08:13:19 -0700549 stats.ana_statistics.bitrate_action_counter = rtc::Optional<uint32_t>(321);
550 stats.ana_statistics.channel_action_counter = rtc::Optional<uint32_t>(432);
551 stats.ana_statistics.dtx_action_counter = rtc::Optional<uint32_t>(543);
552 stats.ana_statistics.fec_action_counter = rtc::Optional<uint32_t>(654);
ivoc0d0b9122017-09-08 13:24:21 -0700553 stats.ana_statistics.frame_length_increase_counter =
ivoce1198e02017-09-08 08:13:19 -0700554 rtc::Optional<uint32_t>(765);
ivoc0d0b9122017-09-08 13:24:21 -0700555 stats.ana_statistics.frame_length_decrease_counter =
556 rtc::Optional<uint32_t>(876);
557 stats.ana_statistics.uplink_packet_loss_fraction =
558 rtc::Optional<float>(987.0);
solenberg85a04962015-10-27 03:35:21 -0700559 stats.typing_noise_detected = true;
560 return stats;
561 }
562 void SetAudioSendStreamStats() {
563 for (auto* s : call_.GetAudioSendStreams()) {
564 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200565 }
solenberg85a04962015-10-27 03:35:21 -0700566 }
solenberg566ef242015-11-06 15:34:49 -0800567 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
568 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700569 const auto stats = GetAudioSendStreamStats();
570 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
571 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
572 EXPECT_EQ(info.packets_sent, stats.packets_sent);
573 EXPECT_EQ(info.packets_lost, stats.packets_lost);
574 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
575 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800576 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700577 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
578 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
579 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
580 EXPECT_EQ(info.audio_level, stats.audio_level);
581 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
582 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
583 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
584 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
585 EXPECT_EQ(info.echo_return_loss_enhancement,
586 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700587 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800588 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
589 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700590 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
591 stats.ana_statistics.bitrate_action_counter);
592 EXPECT_EQ(info.ana_statistics.channel_action_counter,
593 stats.ana_statistics.channel_action_counter);
594 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
595 stats.ana_statistics.dtx_action_counter);
596 EXPECT_EQ(info.ana_statistics.fec_action_counter,
597 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700598 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
599 stats.ana_statistics.frame_length_increase_counter);
600 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
601 stats.ana_statistics.frame_length_decrease_counter);
602 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
603 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800604 EXPECT_EQ(info.typing_noise_detected,
605 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700606 }
607
608 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
609 webrtc::AudioReceiveStream::Stats stats;
610 stats.remote_ssrc = 123;
611 stats.bytes_rcvd = 456;
612 stats.packets_rcvd = 768;
613 stats.packets_lost = 101;
614 stats.fraction_lost = 23.45f;
615 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800616 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700617 stats.ext_seqnum = 678;
618 stats.jitter_ms = 901;
619 stats.jitter_buffer_ms = 234;
620 stats.jitter_buffer_preferred_ms = 567;
621 stats.delay_estimate_ms = 890;
622 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700623 stats.total_samples_received = 5678901;
624 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200625 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200626 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700627 stats.expand_rate = 5.67f;
628 stats.speech_expand_rate = 8.90f;
629 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200630 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700631 stats.accelerate_rate = 4.56f;
632 stats.preemptive_expand_rate = 7.89f;
633 stats.decoding_calls_to_silence_generator = 12;
634 stats.decoding_calls_to_neteq = 345;
635 stats.decoding_normal = 67890;
636 stats.decoding_plc = 1234;
637 stats.decoding_cng = 5678;
638 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700639 stats.decoding_muted_output = 3456;
640 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200641 return stats;
642 }
643 void SetAudioReceiveStreamStats() {
644 for (auto* s : call_.GetAudioReceiveStreams()) {
645 s->SetStats(GetAudioReceiveStreamStats());
646 }
647 }
648 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700649 const auto stats = GetAudioReceiveStreamStats();
650 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
651 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
652 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
653 EXPECT_EQ(info.packets_lost, stats.packets_lost);
654 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
655 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800656 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700657 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
658 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
659 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200660 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700661 stats.jitter_buffer_preferred_ms);
662 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
663 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700664 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
665 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200666 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200667 EXPECT_EQ(info.jitter_buffer_delay_seconds,
668 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700669 EXPECT_EQ(info.expand_rate, stats.expand_rate);
670 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
671 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200672 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700673 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
674 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200675 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700676 stats.decoding_calls_to_silence_generator);
677 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
678 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
679 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
680 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
681 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700682 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700683 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200684 }
hbos1acfbd22016-11-17 23:43:29 -0800685 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
686 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
687 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
688 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
689 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
690 codec.ToCodecParameters());
691 }
692 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
693 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
694 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
695 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
696 codec.ToCodecParameters());
697 }
698 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200699
peah8271d042016-11-22 07:24:52 -0800700 bool IsHighPassFilterEnabled() {
701 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
702 }
703
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700705 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700706 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800707 webrtc::test::MockGainControl& apm_gc_;
708 webrtc::test::MockEchoCancellation& apm_ec_;
709 webrtc::test::MockNoiseSuppression& apm_ns_;
710 webrtc::test::MockVoiceDetection& apm_vd_;
711 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700712 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200713 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700715 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700716 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200717 cricket::AudioSendParameters send_parameters_;
718 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800719 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700720 webrtc::AudioProcessing::Config apm_config_;
721
stefanba4c0e42016-02-04 04:12:24 -0800722 private:
723 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724};
725
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726// Tests that we can create and destroy a channel.
727TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700728 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729}
730
solenberg31fec402016-05-06 02:13:12 -0700731// Test that we can add a send stream and that it has the correct defaults.
732TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
733 EXPECT_TRUE(SetupChannel());
734 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800735 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
736 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
737 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700738 EXPECT_EQ("", config.rtp.c_name);
739 EXPECT_EQ(0u, config.rtp.extensions.size());
740 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
741 config.send_transport);
742}
743
744// Test that we can add a receive stream and that it has the correct defaults.
745TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
746 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800747 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700748 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800749 GetRecvStreamConfig(kSsrcX);
750 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700751 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
752 EXPECT_FALSE(config.rtp.transport_cc);
753 EXPECT_EQ(0u, config.rtp.extensions.size());
754 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
755 config.rtcp_send_transport);
756 EXPECT_EQ("", config.sync_group);
757}
758
stefanba4c0e42016-02-04 04:12:24 -0800759TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700760 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800761 bool opus_found = false;
762 for (cricket::AudioCodec codec : codecs) {
763 if (codec.name == "opus") {
764 EXPECT_TRUE(HasTransportCc(codec));
765 opus_found = true;
766 }
767 }
768 EXPECT_TRUE(opus_found);
769}
770
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771// Test that we set our inbound codecs properly, including changing PT.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800777 parameters.codecs.push_back(kTelephoneEventCodec1);
778 parameters.codecs.push_back(kTelephoneEventCodec2);
779 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200780 parameters.codecs[2].id = 126;
781 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800782 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700783 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
784 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
785 {{0, {"PCMU", 8000, 1}},
786 {106, {"ISAC", 16000, 1}},
787 {126, {"telephone-event", 8000, 1}},
788 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789}
790
791// Test that we fail to set an unknown inbound codec.
792TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700793 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200794 cricket::AudioRecvParameters parameters;
795 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700796 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200797 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798}
799
800// Test that we fail if we have duplicate types in the inbound list.
801TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700802 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200803 cricket::AudioRecvParameters parameters;
804 parameters.codecs.push_back(kIsacCodec);
805 parameters.codecs.push_back(kCn16000Codec);
806 parameters.codecs[1].id = kIsacCodec.id;
807 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that we can decode OPUS without stereo parameters.
811TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700812 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 cricket::AudioRecvParameters parameters;
814 parameters.codecs.push_back(kIsacCodec);
815 parameters.codecs.push_back(kPcmuCodec);
816 parameters.codecs.push_back(kOpusCodec);
817 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800818 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700819 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
820 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
821 {{0, {"PCMU", 8000, 1}},
822 {103, {"ISAC", 16000, 1}},
823 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826// Test that we can decode OPUS with stereo = 0.
827TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700828 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200829 cricket::AudioRecvParameters parameters;
830 parameters.codecs.push_back(kIsacCodec);
831 parameters.codecs.push_back(kPcmuCodec);
832 parameters.codecs.push_back(kOpusCodec);
833 parameters.codecs[2].params["stereo"] = "0";
834 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800835 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700836 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
837 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
838 {{0, {"PCMU", 8000, 1}},
839 {103, {"ISAC", 16000, 1}},
840 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843// Test that we can decode OPUS with stereo = 1.
844TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700845 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 cricket::AudioRecvParameters parameters;
847 parameters.codecs.push_back(kIsacCodec);
848 parameters.codecs.push_back(kPcmuCodec);
849 parameters.codecs.push_back(kOpusCodec);
850 parameters.codecs[2].params["stereo"] = "1";
851 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700853 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
854 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
855 {{0, {"PCMU", 8000, 1}},
856 {103, {"ISAC", 16000, 1}},
857 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858}
859
860// Test that changes to recv codecs are applied to all streams.
861TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700862 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 cricket::AudioRecvParameters parameters;
864 parameters.codecs.push_back(kIsacCodec);
865 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800866 parameters.codecs.push_back(kTelephoneEventCodec1);
867 parameters.codecs.push_back(kTelephoneEventCodec2);
868 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200869 parameters.codecs[2].id = 126;
870 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700871 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
872 EXPECT_TRUE(AddRecvStream(ssrc));
873 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
874 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
875 {{0, {"PCMU", 8000, 1}},
876 {106, {"ISAC", 16000, 1}},
877 {126, {"telephone-event", 8000, 1}},
878 {107, {"telephone-event", 32000, 1}}})));
879 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880}
881
882TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700883 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 cricket::AudioRecvParameters parameters;
885 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800886 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888
solenberg2100c0b2017-03-01 11:29:29 -0800889 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800890 ASSERT_EQ(1, dm.count(106));
891 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892}
893
894// Test that we can apply the same set of codecs again while playing.
895TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700896 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200897 cricket::AudioRecvParameters parameters;
898 parameters.codecs.push_back(kIsacCodec);
899 parameters.codecs.push_back(kCn16000Codec);
900 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700901 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
deadbeefcb383672017-04-26 16:28:42 -0700904 // Remapping a payload type to a different codec should fail.
905 parameters.codecs[0] = kOpusCodec;
906 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200907 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800908 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911// Test that we can add a codec while playing.
912TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700913 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200914 cricket::AudioRecvParameters parameters;
915 parameters.codecs.push_back(kIsacCodec);
916 parameters.codecs.push_back(kCn16000Codec);
917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700918 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 parameters.codecs.push_back(kOpusCodec);
921 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800922 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
deadbeefcb383672017-04-26 16:28:42 -0700925// Test that we accept adding the same codec with a different payload type.
926// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
927TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
928 EXPECT_TRUE(SetupRecvStream());
929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
932
933 ++parameters.codecs[0].id;
934 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
935}
936
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700938 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000940 // Test that when autobw is enabled, bitrate is kept as the default
941 // value. autobw is enabled for the following tests because the target
942 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
944 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700945 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000946
947 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700948 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949
ossu20a4b3f2017-04-27 02:08:52 -0700950 // opus, default bitrate == 32000 in mono.
951 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952}
953
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000954TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700955 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700958 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
959 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700960 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
964 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
965 // Rates above the max (510000) should be capped.
966 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967}
968
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700970 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971
972 // Test that we can only set a maximum bitrate for a fixed-rate codec
973 // if it's bigger than the fixed rate.
974
975 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700976 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
977 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
978 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000983}
984
985TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700986 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200987 const int kDesiredBitrate = 128000;
988 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700989 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200990 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700991 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000992
993 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800994 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000995
solenberg2100c0b2017-03-01 11:29:29 -0800996 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000997}
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999// Test that bitrate cannot be set for CBR codecs.
1000// Bitrate is ignored if it is higher than the fixed bitrate.
1001// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001002TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001003 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001006 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008
1009 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001010 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001011 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001012
1013 send_parameters_.max_bandwidth_bps = 128;
1014 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016}
1017
skvlade0d46372016-04-07 22:59:22 -07001018// Test that the per-stream bitrate limit and the global
1019// bitrate limit both apply.
1020TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1021 EXPECT_TRUE(SetupSendStream());
1022
ossu20a4b3f2017-04-27 02:08:52 -07001023 // opus, default bitrate == 32000.
1024 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001025 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1026 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1027 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1028
1029 // CBR codecs allow both maximums to exceed the bitrate.
1030 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1031 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1034
1035 // CBR codecs don't allow per stream maximums to be too low.
1036 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1037 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1038}
1039
1040// Test that an attempt to set RtpParameters for a stream that does not exist
1041// fails.
1042TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1043 EXPECT_TRUE(SetupChannel());
1044 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001045 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001046 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1047
1048 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001049 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001050}
1051
1052TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001053 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001054 // This test verifies that setting RtpParameters succeeds only if
1055 // the structure contains exactly one encoding.
1056 // TODO(skvlad): Update this test when we start supporting setting parameters
1057 // for each encoding individually.
1058
1059 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001060 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001061 // Two or more encodings should result in failure.
1062 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001063 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001064 // Zero encodings should also fail.
1065 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001066 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001067}
1068
1069// Changing the SSRC through RtpParameters is not allowed.
1070TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1071 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001072 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001073 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001074 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001075}
1076
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001077// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001078// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1080 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001081 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001082 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001083 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001084 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085 ASSERT_EQ(1u, parameters.encodings.size());
1086 ASSERT_TRUE(parameters.encodings[0].active);
1087 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001088 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1089 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001090
1091 // Now change it back to active and verify we resume sending.
1092 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001093 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1094 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001095}
1096
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097// Test that SetRtpSendParameters configures the correct encoding channel for
1098// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001099TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1100 SetupForMultiSendStream();
1101 // Create send streams.
1102 for (uint32_t ssrc : kSsrcs4) {
1103 EXPECT_TRUE(
1104 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1105 }
1106 // Configure one stream to be limited by the stream config, another to be
1107 // limited by the global max, and the third one with no per-stream limit
1108 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001109 SetGlobalMaxBitrate(kOpusCodec, 32000);
1110 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1111 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001112 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1113
ossu20a4b3f2017-04-27 02:08:52 -07001114 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1115 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1116 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001117
1118 // Remove the global cap; the streams should switch to their respective
1119 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001120 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001121 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1122 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1123 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001124}
1125
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001126// Test that GetRtpSendParameters returns the currently configured codecs.
1127TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001128 EXPECT_TRUE(SetupSendStream());
1129 cricket::AudioSendParameters parameters;
1130 parameters.codecs.push_back(kIsacCodec);
1131 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001132 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001133
solenberg2100c0b2017-03-01 11:29:29 -08001134 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001136 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1137 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001138}
1139
deadbeefcb443432016-12-12 11:12:36 -08001140// Test that GetRtpSendParameters returns an SSRC.
1141TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1142 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001143 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001144 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001145 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001146}
1147
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001148// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001149TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 EXPECT_TRUE(SetupSendStream());
1151 cricket::AudioSendParameters parameters;
1152 parameters.codecs.push_back(kIsacCodec);
1153 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001154 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155
solenberg2100c0b2017-03-01 11:29:29 -08001156 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157
1158 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001159 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001160
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001161 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001162 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1163 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001164}
1165
minyuececec102017-03-27 13:04:25 -07001166// Test that max_bitrate_bps in send stream config gets updated correctly when
1167// SetRtpSendParameters is called.
1168TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1169 webrtc::test::ScopedFieldTrials override_field_trials(
1170 "WebRTC-Audio-SendSideBwe/Enabled/");
1171 EXPECT_TRUE(SetupSendStream());
1172 cricket::AudioSendParameters send_parameters;
1173 send_parameters.codecs.push_back(kOpusCodec);
1174 SetSendParameters(send_parameters);
1175
1176 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1177 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1178 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1179
1180 constexpr int kMaxBitrateBps = 6000;
1181 rtp_parameters.encodings[0].max_bitrate_bps =
1182 rtc::Optional<int>(kMaxBitrateBps);
1183 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1184
1185 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1186 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1187}
1188
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001189// Test that GetRtpReceiveParameters returns the currently configured codecs.
1190TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1191 EXPECT_TRUE(SetupRecvStream());
1192 cricket::AudioRecvParameters parameters;
1193 parameters.codecs.push_back(kIsacCodec);
1194 parameters.codecs.push_back(kPcmuCodec);
1195 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1196
1197 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001198 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001199 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1200 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1201 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1202}
1203
deadbeefcb443432016-12-12 11:12:36 -08001204// Test that GetRtpReceiveParameters returns an SSRC.
1205TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1206 EXPECT_TRUE(SetupRecvStream());
1207 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001208 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001209 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001210 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001211}
1212
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001213// Test that if we set/get parameters multiple times, we get the same results.
1214TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1215 EXPECT_TRUE(SetupRecvStream());
1216 cricket::AudioRecvParameters parameters;
1217 parameters.codecs.push_back(kIsacCodec);
1218 parameters.codecs.push_back(kPcmuCodec);
1219 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1220
1221 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001222 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001223
1224 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001225 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001226
1227 // ... And this shouldn't change the params returned by
1228 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001229 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1230 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001231}
1232
deadbeef3bc15102017-04-20 19:25:07 -07001233// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1234// aren't signaled. It should return an empty "RtpEncodingParameters" when
1235// configured to receive an unsignaled stream and no packets have been received
1236// yet, and start returning the SSRC once a packet has been received.
1237TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1238 ASSERT_TRUE(SetupChannel());
1239 // Call necessary methods to configure receiving a default stream as
1240 // soon as it arrives.
1241 cricket::AudioRecvParameters parameters;
1242 parameters.codecs.push_back(kIsacCodec);
1243 parameters.codecs.push_back(kPcmuCodec);
1244 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1245
1246 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1247 // stream. Should return nothing.
1248 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1249
1250 // Set a sink for an unsignaled stream.
1251 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1252 // Value of "0" means "unsignaled stream".
1253 channel_->SetRawAudioSink(0, std::move(fake_sink));
1254
1255 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1256 // in this method means "unsignaled stream".
1257 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1258 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1259 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1260
1261 // Receive PCMU packet (SSRC=1).
1262 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1263
1264 // The |ssrc| member should still be unset.
1265 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1266 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1267 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1268}
1269
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001270// Test that we apply codecs properly.
1271TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001272 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001273 cricket::AudioSendParameters parameters;
1274 parameters.codecs.push_back(kIsacCodec);
1275 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001276 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001277 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001278 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001279 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001280 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1281 EXPECT_EQ(96, send_codec_spec.payload_type);
1282 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1283 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1284 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1285 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001286 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001287}
1288
ossu20a4b3f2017-04-27 02:08:52 -07001289// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1290// AudioSendStream.
1291TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001292 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001293 cricket::AudioSendParameters parameters;
1294 parameters.codecs.push_back(kIsacCodec);
1295 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001296 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001297 parameters.codecs[0].id = 96;
1298 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001299 const int initial_num = call_.GetNumCreatedSendStreams();
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 // Calling SetSendCodec again with same codec which is already set.
1303 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001304 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001305 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001306}
1307
ossu20a4b3f2017-04-27 02:08:52 -07001308// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1309// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001310
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001311// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001313 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001314 cricket::AudioSendParameters parameters;
1315 parameters.codecs.push_back(kOpusCodec);
1316 parameters.codecs[0].bitrate = 0;
1317 parameters.codecs[0].clockrate = 50000;
1318 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319}
1320
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001321// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001323 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001324 cricket::AudioSendParameters parameters;
1325 parameters.codecs.push_back(kOpusCodec);
1326 parameters.codecs[0].bitrate = 0;
1327 parameters.codecs[0].channels = 0;
1328 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329}
1330
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001331// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001333 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001334 cricket::AudioSendParameters parameters;
1335 parameters.codecs.push_back(kOpusCodec);
1336 parameters.codecs[0].bitrate = 0;
1337 parameters.codecs[0].channels = 0;
1338 parameters.codecs[0].params["stereo"] = "1";
1339 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340}
1341
1342// Test that if channel is 1 for opus and there's no stereo, we fail.
1343TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001344 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001345 cricket::AudioSendParameters parameters;
1346 parameters.codecs.push_back(kOpusCodec);
1347 parameters.codecs[0].bitrate = 0;
1348 parameters.codecs[0].channels = 1;
1349 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350}
1351
1352// Test that if channel is 1 for opus and stereo=0, we fail.
1353TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001354 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001355 cricket::AudioSendParameters parameters;
1356 parameters.codecs.push_back(kOpusCodec);
1357 parameters.codecs[0].bitrate = 0;
1358 parameters.codecs[0].channels = 1;
1359 parameters.codecs[0].params["stereo"] = "0";
1360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361}
1362
1363// Test that if channel is 1 for opus and stereo=1, we fail.
1364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kOpusCodec);
1368 parameters.codecs[0].bitrate = 0;
1369 parameters.codecs[0].channels = 1;
1370 parameters.codecs[0].params["stereo"] = "1";
1371 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372}
1373
ossu20a4b3f2017-04-27 02:08:52 -07001374// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001376 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 cricket::AudioSendParameters parameters;
1378 parameters.codecs.push_back(kOpusCodec);
1379 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001380 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001381 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382}
1383
ossu20a4b3f2017-04-27 02:08:52 -07001384// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001391 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001392 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393}
1394
ossu20a4b3f2017-04-27 02:08:52 -07001395// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001401 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001403 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001404 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001405
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001406 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001407 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001408 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001409}
1410
ossu20a4b3f2017-04-27 02:08:52 -07001411// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001413 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 cricket::AudioSendParameters parameters;
1415 parameters.codecs.push_back(kOpusCodec);
1416 parameters.codecs[0].bitrate = 0;
1417 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001418 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001419 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001420}
1421
ossu20a4b3f2017-04-27 02:08:52 -07001422// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001424 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001425 cricket::AudioSendParameters parameters;
1426 parameters.codecs.push_back(kOpusCodec);
1427 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001428 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001430 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001431 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001432
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001433 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001434 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001435 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001436}
1437
ossu20a4b3f2017-04-27 02:08:52 -07001438// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001440 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 cricket::AudioSendParameters parameters;
1442 parameters.codecs.push_back(kOpusCodec);
1443 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001444 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001445 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1446 EXPECT_EQ(111, spec.payload_type);
1447 EXPECT_EQ(96000, spec.target_bitrate_bps);
1448 EXPECT_EQ("opus", spec.format.name);
1449 EXPECT_EQ(2, spec.format.num_channels);
1450 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
ossu20a4b3f2017-04-27 02:08:52 -07001453// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001455 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001456 cricket::AudioSendParameters parameters;
1457 parameters.codecs.push_back(kOpusCodec);
1458 parameters.codecs[0].bitrate = 30000;
1459 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001461 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462}
1463
ossu20a4b3f2017-04-27 02:08:52 -07001464// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001466 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 cricket::AudioSendParameters parameters;
1468 parameters.codecs.push_back(kOpusCodec);
1469 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001470 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001471 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001472}
1473
ossu20a4b3f2017-04-27 02:08:52 -07001474// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001476 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001477 cricket::AudioSendParameters parameters;
1478 parameters.codecs.push_back(kOpusCodec);
1479 parameters.codecs[0].bitrate = 30000;
1480 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001481 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001482 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001483}
1484
stefan13f1a0a2016-11-30 07:22:58 -08001485TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1486 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1487 200000);
1488}
1489
1490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1491 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1492}
1493
1494TEST_F(WebRtcVoiceEngineTestFake,
1495 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1496 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1497}
1498
1499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1500 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1501}
1502
1503TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001504 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001505 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1506 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001507 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001508 SetSendParameters(send_parameters_);
1509 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1510 << "Setting max bitrate should keep previous min bitrate.";
1511 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1512 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001513 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001514}
1515
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001516// Test that we can enable NACK with opus as caller.
1517TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001518 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::AudioSendParameters parameters;
1520 parameters.codecs.push_back(kOpusCodec);
1521 parameters.codecs[0].AddFeedbackParam(
1522 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1523 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001524 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001525 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001526 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001529// Test that we can enable NACK with opus as callee.
1530TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001531 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001532 cricket::AudioSendParameters parameters;
1533 parameters.codecs.push_back(kOpusCodec);
1534 parameters.codecs[0].AddFeedbackParam(
1535 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1536 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001538 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001539 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001541
1542 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001543 cricket::StreamParams::CreateLegacy(kSsrcX)));
1544 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001545}
1546
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547// Test that we can enable NACK on receive streams.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001549 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001550 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001551 cricket::AudioSendParameters parameters;
1552 parameters.codecs.push_back(kOpusCodec);
1553 parameters.codecs[0].AddFeedbackParam(
1554 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1555 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1557 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001558 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001559 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1560 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561}
1562
1563// Test that we can disable NACK.
1564TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001565 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001566 cricket::AudioSendParameters parameters;
1567 parameters.codecs.push_back(kOpusCodec);
1568 parameters.codecs[0].AddFeedbackParam(
1569 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1570 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001571 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001574 parameters.codecs.clear();
1575 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578}
1579
1580// Test that we can disable NACK on receive streams.
1581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001583 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001584 cricket::AudioSendParameters parameters;
1585 parameters.codecs.push_back(kOpusCodec);
1586 parameters.codecs[0].AddFeedbackParam(
1587 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1588 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1591 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001593 parameters.codecs.clear();
1594 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001595 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001596 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1597 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598}
1599
1600// Test that NACK is enabled on a new receive stream.
1601TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001602 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001603 cricket::AudioSendParameters parameters;
1604 parameters.codecs.push_back(kIsacCodec);
1605 parameters.codecs.push_back(kCn16000Codec);
1606 parameters.codecs[0].AddFeedbackParam(
1607 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1608 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_TRUE(AddRecvStream(kSsrcY));
1613 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1614 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1615 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616}
1617
stefanba4c0e42016-02-04 04:12:24 -08001618TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001619 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001620 cricket::AudioSendParameters send_parameters;
1621 send_parameters.codecs.push_back(kOpusCodec);
1622 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001624
1625 cricket::AudioRecvParameters recv_parameters;
1626 recv_parameters.codecs.push_back(kIsacCodec);
1627 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_TRUE(AddRecvStream(kSsrcX));
1629 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001630 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001631 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001632
ossudedfd282016-06-14 07:12:39 -07001633 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001634 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001635 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001636 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001637 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001638}
1639
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001640// Test that we can switch back and forth between Opus and ISAC with CN.
1641TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001642 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001643
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters opus_parameters;
1645 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001647 {
ossu20a4b3f2017-04-27 02:08:52 -07001648 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1649 EXPECT_EQ(111, spec.payload_type);
1650 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001651 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001652
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001653 cricket::AudioSendParameters isac_parameters;
1654 isac_parameters.codecs.push_back(kIsacCodec);
1655 isac_parameters.codecs.push_back(kCn16000Codec);
1656 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001657 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001658 {
ossu20a4b3f2017-04-27 02:08:52 -07001659 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1660 EXPECT_EQ(103, spec.payload_type);
1661 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001662 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001663
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001665 {
ossu20a4b3f2017-04-27 02:08:52 -07001666 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1667 EXPECT_EQ(111, spec.payload_type);
1668 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001669 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670}
1671
1672// Test that we handle various ways of specifying bitrate.
1673TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001674 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001675 cricket::AudioSendParameters parameters;
1676 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001677 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001678 {
ossu20a4b3f2017-04-27 02:08:52 -07001679 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1680 EXPECT_EQ(103, spec.payload_type);
1681 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1682 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001686 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001687 {
ossu20a4b3f2017-04-27 02:08:52 -07001688 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1689 EXPECT_EQ(103, spec.payload_type);
1690 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1691 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001692 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001693 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001694 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001695 {
ossu20a4b3f2017-04-27 02:08:52 -07001696 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1697 EXPECT_EQ(103, spec.payload_type);
1698 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1699 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001700 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001702 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001703 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001704 {
ossu20a4b3f2017-04-27 02:08:52 -07001705 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1706 EXPECT_EQ(0, spec.payload_type);
1707 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1708 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001710
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001711 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001712 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001713 {
ossu20a4b3f2017-04-27 02:08:52 -07001714 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1715 EXPECT_EQ(0, spec.payload_type);
1716 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1717 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001718 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001720 parameters.codecs[0] = kOpusCodec;
1721 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001723 {
ossu20a4b3f2017-04-27 02:08:52 -07001724 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1725 EXPECT_EQ(111, spec.payload_type);
1726 EXPECT_STREQ("opus", spec.format.name.c_str());
1727 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001728 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729}
1730
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001731// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001733 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 cricket::AudioSendParameters parameters;
1735 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001736}
1737
1738// Test that we can set send codecs even with telephone-event codec as the first
1739// one on the list.
1740TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001741 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001743 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 parameters.codecs.push_back(kIsacCodec);
1745 parameters.codecs.push_back(kPcmuCodec);
1746 parameters.codecs[0].id = 98; // DTMF
1747 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001748 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001749 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1750 EXPECT_EQ(96, spec.payload_type);
1751 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001752 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001753}
1754
solenberg31642aa2016-03-14 08:00:37 -07001755// Test that payload type range is limited for telephone-event codec.
1756TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001757 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001758 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001759 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001760 parameters.codecs.push_back(kIsacCodec);
1761 parameters.codecs[0].id = 0; // DTMF
1762 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001763 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001764 EXPECT_TRUE(channel_->CanInsertDtmf());
1765 parameters.codecs[0].id = 128; // DTMF
1766 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1767 EXPECT_FALSE(channel_->CanInsertDtmf());
1768 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001769 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001770 EXPECT_TRUE(channel_->CanInsertDtmf());
1771 parameters.codecs[0].id = -1; // DTMF
1772 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1773 EXPECT_FALSE(channel_->CanInsertDtmf());
1774}
1775
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001776// Test that we can set send codecs even with CN codec as the first
1777// one on the list.
1778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001779 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001780 cricket::AudioSendParameters parameters;
1781 parameters.codecs.push_back(kCn16000Codec);
1782 parameters.codecs.push_back(kIsacCodec);
1783 parameters.codecs.push_back(kPcmuCodec);
1784 parameters.codecs[0].id = 98; // wideband CN
1785 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001787 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1788 EXPECT_EQ(96, send_codec_spec.payload_type);
1789 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001790 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001791}
1792
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001793// Test that we set VAD and DTMF types correctly as caller.
1794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001795 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001796 cricket::AudioSendParameters parameters;
1797 parameters.codecs.push_back(kIsacCodec);
1798 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001799 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 parameters.codecs.push_back(kCn16000Codec);
1801 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001802 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 parameters.codecs[0].id = 96;
1804 parameters.codecs[2].id = 97; // wideband CN
1805 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001806 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001807 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1808 EXPECT_EQ(96, send_codec_spec.payload_type);
1809 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1810 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001811 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001812 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813}
1814
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001815// Test that we set VAD and DTMF types correctly as callee.
1816TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 cricket::AudioSendParameters parameters;
1819 parameters.codecs.push_back(kIsacCodec);
1820 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001821 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001822 parameters.codecs.push_back(kCn16000Codec);
1823 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001824 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001825 parameters.codecs[0].id = 96;
1826 parameters.codecs[2].id = 97; // wideband CN
1827 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001829 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001830 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001831
ossu20a4b3f2017-04-27 02:08:52 -07001832 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1833 EXPECT_EQ(96, send_codec_spec.payload_type);
1834 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1835 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001836 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001837 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001838}
1839
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001840// Test that we only apply VAD if we have a CN codec that matches the
1841// send codec clockrate.
1842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001843 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001844 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001845 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001846 parameters.codecs.push_back(kIsacCodec);
1847 parameters.codecs.push_back(kCn16000Codec);
1848 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001849 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001850 {
ossu20a4b3f2017-04-27 02:08:52 -07001851 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1852 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1853 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001854 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001855 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001856 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001857 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001858 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001859 {
ossu20a4b3f2017-04-27 02:08:52 -07001860 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1861 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1862 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001863 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001865 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001866 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001867 {
ossu20a4b3f2017-04-27 02:08:52 -07001868 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1869 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1870 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001871 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001872 }
Brave Yao5225dd82015-03-26 07:39:19 +08001873 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001874 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001875 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001876 {
ossu20a4b3f2017-04-27 02:08:52 -07001877 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1878 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1879 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001880 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001881}
1882
1883// Test that we perform case-insensitive matching of codec names.
1884TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001885 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 cricket::AudioSendParameters parameters;
1887 parameters.codecs.push_back(kIsacCodec);
1888 parameters.codecs.push_back(kPcmuCodec);
1889 parameters.codecs.push_back(kCn16000Codec);
1890 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001891 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 parameters.codecs[0].name = "iSaC";
1893 parameters.codecs[0].id = 96;
1894 parameters.codecs[2].id = 97; // wideband CN
1895 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001896 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001897 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1898 EXPECT_EQ(96, send_codec_spec.payload_type);
1899 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1900 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001901 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001902 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001903}
1904
stefanba4c0e42016-02-04 04:12:24 -08001905class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1906 public:
1907 WebRtcVoiceEngineWithSendSideBweTest()
1908 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1909};
1910
1911TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1912 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001913 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001914 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001915 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1916 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1917 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001918 extension.id);
1919 return;
1920 }
1921 }
1922 FAIL() << "Transport sequence number extension not in header-extension list.";
1923}
1924
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001925// Test support for audio level header extension.
1926TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001927 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001928}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001929TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001930 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001931}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001932
solenbergd4adce42016-11-17 06:26:52 -08001933// Test support for transport sequence number header extension.
1934TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1935 TestSetSendRtpHeaderExtensions(
1936 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001937}
solenbergd4adce42016-11-17 06:26:52 -08001938TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1939 TestSetRecvRtpHeaderExtensions(
1940 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001941}
1942
solenberg1ac56142015-10-13 03:58:19 -07001943// Test that we can create a channel and start sending on it.
1944TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001945 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001946 SetSendParameters(send_parameters_);
1947 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001948 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001949 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001950 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001951}
1952
1953// Test that a channel will send if and only if it has a source and is enabled
1954// for sending.
1955TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001956 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001957 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001958 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001959 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001960 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1961 SetAudioSend(kSsrcX, true, &fake_source_);
1962 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1963 SetAudioSend(kSsrcX, true, nullptr);
1964 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001965}
1966
solenberg94218532016-06-16 10:53:22 -07001967// Test that a channel is muted/unmuted.
1968TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1969 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001971 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1972 SetAudioSend(kSsrcX, true, nullptr);
1973 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1974 SetAudioSend(kSsrcX, false, nullptr);
1975 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001976}
1977
solenberg6d6e7c52016-04-13 09:07:30 -07001978// Test that SetSendParameters() does not alter a stream's send state.
1979TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1980 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001981 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001982
1983 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001984 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001986
1987 // Changing RTP header extensions will recreate the AudioSendStream.
1988 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001989 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001990 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001991 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001992
1993 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001994 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001995 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001996
1997 // Changing RTP header extensions will recreate the AudioSendStream.
1998 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001999 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002000 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002001}
2002
solenberg1ac56142015-10-13 03:58:19 -07002003// Test that we can create a channel and start playing out on it.
2004TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002005 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002006 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002007 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002008 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002009 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002010 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002011}
2012
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002013// Test that we can add and remove send streams.
2014TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2015 SetupForMultiSendStream();
2016
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002017 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002018 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019
solenbergc96df772015-10-21 13:01:53 -07002020 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002022 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002023 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002024 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002025 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002026 }
tfarina5237aaf2015-11-10 23:44:30 -08002027 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002028
solenbergc96df772015-10-21 13:01:53 -07002029 // Delete the send streams.
2030 for (uint32_t ssrc : kSsrcs4) {
2031 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002032 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002033 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034 }
solenbergc96df772015-10-21 13:01:53 -07002035 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036}
2037
2038// Test SetSendCodecs correctly configure the codecs in all send streams.
2039TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2040 SetupForMultiSendStream();
2041
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002043 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002045 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 }
2047
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002048 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002050 parameters.codecs.push_back(kIsacCodec);
2051 parameters.codecs.push_back(kCn16000Codec);
2052 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002053 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054
2055 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002056 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002057 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2058 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002059 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2060 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2061 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002062 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002063 }
2064
minyue7a973442016-10-20 03:27:12 -07002065 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002066 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002067 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002068 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002069 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2070 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002071 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2072 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2073 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002074 }
2075}
2076
2077// Test we can SetSend on all send streams correctly.
2078TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2079 SetupForMultiSendStream();
2080
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002081 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002082 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002084 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002085 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002086 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002087 }
2088
2089 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002090 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002091 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002092 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002093 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 }
2095
2096 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002097 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002098 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002100 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 }
2102}
2103
2104// Test we can set the correct statistics on all send streams.
2105TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2106 SetupForMultiSendStream();
2107
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002108 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002109 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002111 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 }
solenberg85a04962015-10-27 03:35:21 -07002113
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002114 // Create a receive stream to check that none of the send streams end up in
2115 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002116 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002117
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002118 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002119 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002120 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002121 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122
solenberg85a04962015-10-27 03:35:21 -07002123 // Check stats for the added streams.
2124 {
2125 cricket::VoiceMediaInfo info;
2126 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002127
solenberg85a04962015-10-27 03:35:21 -07002128 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002129 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002130 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002131 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002132 }
hbos1acfbd22016-11-17 23:43:29 -08002133 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002134
2135 // We have added one receive stream. We should see empty stats.
2136 EXPECT_EQ(info.receivers.size(), 1u);
2137 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002138 }
solenberg1ac56142015-10-13 03:58:19 -07002139
solenberg2100c0b2017-03-01 11:29:29 -08002140 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002141 {
2142 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002143 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002144 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002145 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002146 EXPECT_EQ(0u, info.receivers.size());
2147 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002148
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002149 // Deliver a new packet - a default receive stream should be created and we
2150 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002151 {
2152 cricket::VoiceMediaInfo info;
2153 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2154 SetAudioReceiveStreamStats();
2155 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002156 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002157 EXPECT_EQ(1u, info.receivers.size());
2158 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002159 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002160 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002161}
2162
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163// Test that we can add and remove receive streams, and do proper send/playout.
2164// We can receive on multiple streams while sending one stream.
2165TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002166 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167
solenberg1ac56142015-10-13 03:58:19 -07002168 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002169 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002170 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171
solenberg1ac56142015-10-13 03:58:19 -07002172 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002173 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002174 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002175 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002176
solenberg1ac56142015-10-13 03:58:19 -07002177 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002178 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002179
2180 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002181 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2182 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2183 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184
2185 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002186 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002187 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188
2189 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002190 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002191 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2192 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002193
aleloi84ef6152016-08-04 05:28:21 -07002194 // Restart playout and make sure recv streams are played out.
2195 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002196 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2197 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198
aleloi84ef6152016-08-04 05:28:21 -07002199 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002200 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2201 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202}
2203
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002205// and start sending on it.
2206TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002207 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002208 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2209 EXPECT_CALL(apm_gc_,
2210 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002211 SetSendParameters(send_parameters_);
2212 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002213 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002214 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002215 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216}
2217
wu@webrtc.org97077a32013-10-25 21:18:33 +00002218TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002219 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002220 EXPECT_CALL(adm_,
2221 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002222 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2223 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002224 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2225 send_parameters_.options.tx_agc_digital_compression_gain =
2226 rtc::Optional<uint16_t>(9);
2227 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2228 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002229 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2230 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2231 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002232 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002233
2234 // Check interaction with adjust_agc_delta. Both should be respected, for
2235 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002236 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002237 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002238 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002239}
2240
minyue6b825df2016-10-31 04:08:32 -07002241TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2242 EXPECT_TRUE(SetupSendStream());
2243 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2244 send_parameters_.options.audio_network_adaptor_config =
2245 rtc::Optional<std::string>("1234");
2246 SetSendParameters(send_parameters_);
2247 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002248 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002249}
2250
2251TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2252 EXPECT_TRUE(SetupSendStream());
2253 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2254 send_parameters_.options.audio_network_adaptor_config =
2255 rtc::Optional<std::string>("1234");
2256 SetSendParameters(send_parameters_);
2257 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002258 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002259 cricket::AudioOptions options;
2260 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002261 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002262 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002263}
2264
2265TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2266 EXPECT_TRUE(SetupSendStream());
2267 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2268 send_parameters_.options.audio_network_adaptor_config =
2269 rtc::Optional<std::string>("1234");
2270 SetSendParameters(send_parameters_);
2271 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002272 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002273 const int initial_num = call_.GetNumCreatedSendStreams();
2274 cricket::AudioOptions options;
2275 options.audio_network_adaptor = rtc::Optional<bool>();
2276 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2277 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002278 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002279 // AudioSendStream not expected to be recreated.
2280 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2281 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002282 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002283}
2284
michaelt6672b262017-01-11 10:17:59 -08002285class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2286 : public WebRtcVoiceEngineTestFake {
2287 public:
2288 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2289 : WebRtcVoiceEngineTestFake(
2290 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2291 "Enabled/") {}
2292};
2293
2294TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2295 EXPECT_TRUE(SetupSendStream());
2296 cricket::AudioSendParameters parameters;
2297 parameters.codecs.push_back(kOpusCodec);
2298 SetSendParameters(parameters);
2299 const int initial_num = call_.GetNumCreatedSendStreams();
2300 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2301
2302 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2303 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002304 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2305 constexpr int kMinOverheadBps =
2306 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002307
2308 constexpr int kOpusMinBitrateBps = 6000;
2309 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002310 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002311 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002312 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002313 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002314
2315 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2316 parameters.options.audio_network_adaptor_config =
2317 rtc::Optional<std::string>("1234");
2318 SetSendParameters(parameters);
2319
ossu11bfc532017-02-16 05:37:06 -08002320 constexpr int kMinOverheadWithAnaBps =
2321 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002322
2323 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002324 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002325
minyuececec102017-03-27 13:04:25 -07002326 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002327 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002328}
2329
minyuececec102017-03-27 13:04:25 -07002330// This test is similar to
2331// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2332// additional field trial.
2333TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2334 SetRtpSendParameterUpdatesMaxBitrate) {
2335 EXPECT_TRUE(SetupSendStream());
2336 cricket::AudioSendParameters send_parameters;
2337 send_parameters.codecs.push_back(kOpusCodec);
2338 SetSendParameters(send_parameters);
2339
2340 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2341 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2342 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2343
2344 constexpr int kMaxBitrateBps = 6000;
2345 rtp_parameters.encodings[0].max_bitrate_bps =
2346 rtc::Optional<int>(kMaxBitrateBps);
2347 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2348
2349 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2350#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2351 constexpr int kMinOverhead = 3333;
2352#else
2353 constexpr int kMinOverhead = 6666;
2354#endif
2355 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2356}
2357
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002358// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002359// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002360TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002361 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002362 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363}
2364
2365TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2366 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002367 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002368 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002369 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002370 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002371 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002372 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002373 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374
solenberg85a04962015-10-27 03:35:21 -07002375 // Check stats for the added streams.
2376 {
2377 cricket::VoiceMediaInfo info;
2378 EXPECT_EQ(true, channel_->GetStats(&info));
2379
2380 // We have added one send stream. We should see the stats we've set.
2381 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002382 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002383 // We have added one receive stream. We should see empty stats.
2384 EXPECT_EQ(info.receivers.size(), 1u);
2385 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2386 }
solenberg1ac56142015-10-13 03:58:19 -07002387
solenberg566ef242015-11-06 15:34:49 -08002388 // Start sending - this affects some reported stats.
2389 {
2390 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002391 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002392 EXPECT_EQ(true, channel_->GetStats(&info));
2393 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002394 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002395 }
2396
solenberg2100c0b2017-03-01 11:29:29 -08002397 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002398 {
2399 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002400 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002401 EXPECT_EQ(true, channel_->GetStats(&info));
2402 EXPECT_EQ(1u, info.senders.size());
2403 EXPECT_EQ(0u, info.receivers.size());
2404 }
solenberg1ac56142015-10-13 03:58:19 -07002405
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002406 // Deliver a new packet - a default receive stream should be created and we
2407 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002408 {
2409 cricket::VoiceMediaInfo info;
2410 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2411 SetAudioReceiveStreamStats();
2412 EXPECT_EQ(true, channel_->GetStats(&info));
2413 EXPECT_EQ(1u, info.senders.size());
2414 EXPECT_EQ(1u, info.receivers.size());
2415 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002416 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002417 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002421// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002424 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2425 EXPECT_TRUE(AddRecvStream(kSsrcY));
2426 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427}
2428
2429// Test that the local SSRC is the same on sending and receiving channels if the
2430// receive channel is created before the send channel.
2431TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002432 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002433 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002435 cricket::StreamParams::CreateLegacy(kSsrcX)));
2436 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2437 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002438}
2439
2440// Test that we can properly receive packets.
2441TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002442 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002443 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002444 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002445
2446 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2447 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448}
2449
2450// Test that we can properly receive packets on multiple streams.
2451TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002452 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002453 const uint32_t ssrc1 = 1;
2454 const uint32_t ssrc2 = 2;
2455 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002456 EXPECT_TRUE(AddRecvStream(ssrc1));
2457 EXPECT_TRUE(AddRecvStream(ssrc2));
2458 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002460 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002461 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002463 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002464 }
mflodman3d7db262016-04-29 00:57:13 -07002465
2466 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2467 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2468 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2469
2470 EXPECT_EQ(s1.received_packets(), 0);
2471 EXPECT_EQ(s2.received_packets(), 0);
2472 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002473
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002475 EXPECT_EQ(s1.received_packets(), 0);
2476 EXPECT_EQ(s2.received_packets(), 0);
2477 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002478
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002480 EXPECT_EQ(s1.received_packets(), 1);
2481 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2482 EXPECT_EQ(s2.received_packets(), 0);
2483 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002486 EXPECT_EQ(s1.received_packets(), 1);
2487 EXPECT_EQ(s2.received_packets(), 1);
2488 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2489 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002490
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002492 EXPECT_EQ(s1.received_packets(), 1);
2493 EXPECT_EQ(s2.received_packets(), 1);
2494 EXPECT_EQ(s3.received_packets(), 1);
2495 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002496
mflodman3d7db262016-04-29 00:57:13 -07002497 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2498 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2499 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002500}
2501
solenberg2100c0b2017-03-01 11:29:29 -08002502// Test that receiving on an unsignaled stream works (a stream is created).
2503TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002504 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002505 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2506
solenberg7e63ef02015-11-20 00:19:43 -08002507 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002508
2509 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002510 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2511 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002512}
2513
solenberg2100c0b2017-03-01 11:29:29 -08002514// Test that receiving N unsignaled stream works (streams will be created), and
2515// that packets are forwarded to them all.
2516TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002517 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002518 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002519 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2520
solenberg2100c0b2017-03-01 11:29:29 -08002521 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002522 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002523 rtc::SetBE32(&packet[8], ssrc);
2524 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002525
solenberg2100c0b2017-03-01 11:29:29 -08002526 // Verify we have one new stream for each loop iteration.
2527 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002528 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2529 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002530 }
mflodman3d7db262016-04-29 00:57:13 -07002531
solenberg2100c0b2017-03-01 11:29:29 -08002532 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002533 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002534 rtc::SetBE32(&packet[8], ssrc);
2535 DeliverPacket(packet, sizeof(packet));
2536
solenbergebb349d2017-03-13 05:46:15 -07002537 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002538 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2539 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2540 }
2541
2542 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2543 constexpr uint32_t kAnotherSsrc = 667;
2544 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002545 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002546
2547 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002548 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002549 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002550 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002551 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2552 EXPECT_EQ(2, streams[i]->received_packets());
2553 }
2554 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2555 EXPECT_EQ(1, streams[i]->received_packets());
2556 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002557 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002558}
2559
solenberg2100c0b2017-03-01 11:29:29 -08002560// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002561// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002562TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002563 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002564 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002565 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2566
2567 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002568 const uint32_t signaled_ssrc = 1;
2569 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002570 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002571 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002572 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2573 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002574 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002575
2576 // Note that the first unknown SSRC cannot be 0, because we only support
2577 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002578 const uint32_t unsignaled_ssrc = 7011;
2579 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002580 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002581 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2582 packet, sizeof(packet)));
2583 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2584
2585 DeliverPacket(packet, sizeof(packet));
2586 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2587
2588 rtc::SetBE32(&packet[8], signaled_ssrc);
2589 DeliverPacket(packet, sizeof(packet));
2590 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2591 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002592}
2593
solenberg4904fb62017-02-17 12:01:14 -08002594// Two tests to verify that adding a receive stream with the same SSRC as a
2595// previously added unsignaled stream will only recreate underlying stream
2596// objects if the stream parameters have changed.
2597TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2598 EXPECT_TRUE(SetupChannel());
2599
2600 // Spawn unsignaled stream with SSRC=1.
2601 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2602 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2603 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2604 sizeof(kPcmuFrame)));
2605
2606 // Verify that the underlying stream object in Call is not recreated when a
2607 // stream with SSRC=1 is added.
2608 const auto& streams = call_.GetAudioReceiveStreams();
2609 EXPECT_EQ(1, streams.size());
2610 int audio_receive_stream_id = streams.front()->id();
2611 EXPECT_TRUE(AddRecvStream(1));
2612 EXPECT_EQ(1, streams.size());
2613 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2614}
2615
2616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2617 EXPECT_TRUE(SetupChannel());
2618
2619 // Spawn unsignaled stream with SSRC=1.
2620 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2621 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2622 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2623 sizeof(kPcmuFrame)));
2624
2625 // Verify that the underlying stream object in Call *is* recreated when a
2626 // stream with SSRC=1 is added, and which has changed stream parameters.
2627 const auto& streams = call_.GetAudioReceiveStreams();
2628 EXPECT_EQ(1, streams.size());
2629 int audio_receive_stream_id = streams.front()->id();
2630 cricket::StreamParams stream_params;
2631 stream_params.ssrcs.push_back(1);
2632 stream_params.sync_label = "sync_label";
2633 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2634 EXPECT_EQ(1, streams.size());
2635 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2636}
2637
solenberg0a617e22015-10-20 15:49:38 -07002638// Test that we properly handle failures to add a receive stream.
2639TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002640 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002641 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002642 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002643}
2644
solenberg0a617e22015-10-20 15:49:38 -07002645// Test that we properly handle failures to add a send stream.
2646TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002648 voe_.set_fail_create_channel(true);
2649 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2650}
2651
solenberg1ac56142015-10-13 03:58:19 -07002652// Test that AddRecvStream creates new stream.
2653TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002654 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002656 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002657 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002658}
2659
2660// Test that after adding a recv stream, we do not decode more codecs than
2661// those previously passed into SetRecvCodecs.
2662TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002663 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002664 cricket::AudioRecvParameters parameters;
2665 parameters.codecs.push_back(kIsacCodec);
2666 parameters.codecs.push_back(kPcmuCodec);
2667 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002668 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002669 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2670 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2671 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002672}
2673
2674// Test that we properly clean up any streams that were added, even if
2675// not explicitly removed.
2676TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002677 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002678 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002679 EXPECT_TRUE(AddRecvStream(1));
2680 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002681 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2682 delete channel_;
2683 channel_ = NULL;
2684 EXPECT_EQ(0, voe_.GetNumChannels());
2685}
2686
wu@webrtc.org78187522013-10-07 23:32:02 +00002687TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002689 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002690}
2691
2692TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002693 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002694 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002695 // Manually delete channel to simulate a failure.
2696 int channel = voe_.GetLastChannel();
2697 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2698 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002699 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002700 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002701 EXPECT_NE(channel, new_channel);
2702 // The last created channel is deleted too.
2703 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002704}
2705
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002706// Test the InsertDtmf on default send stream as caller.
2707TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002708 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002709}
2710
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002711// Test the InsertDtmf on default send stream as callee
2712TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002713 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002714}
2715
2716// Test the InsertDtmf on specified send stream as caller.
2717TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002718 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002719}
2720
2721// Test the InsertDtmf on specified send stream as callee.
2722TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002723 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002724}
2725
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002726TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002727 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002728 EXPECT_CALL(adm_,
2729 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2730 EXPECT_CALL(adm_,
2731 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2732 EXPECT_CALL(adm_,
2733 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002734
solenberg246b8172015-12-08 09:50:23 -08002735 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2736 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737
solenberg246b8172015-12-08 09:50:23 -08002738 // Nothing set in AudioOptions, so everything should be as default.
2739 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002740 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002741 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002742 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2743 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002744
2745 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002746 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2747 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002748 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002749 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002750
2751 // Turn echo cancellation back on, with settings, and make sure
2752 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002753 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002755 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002758 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2759 // control.
solenberg76377c52017-02-21 00:54:31 -08002760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002762 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002763 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002764
2765 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002766 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2767 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002768 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2769 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2770 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002771 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002772
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002773 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002774 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2775 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002776 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002777 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002778
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002779 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002780 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2781 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2782 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2783 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002784 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002785 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002786
2787 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002788 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2789 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2790 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2791 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002792 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2793 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002794 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002795
2796 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002797 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2798 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2799 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2800 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2802 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2803 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002804 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2805 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2806 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2807 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002808 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002809 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002810
solenberg1ac56142015-10-13 03:58:19 -07002811 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002812 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2814 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2815 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2816 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2817 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2818 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002819 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820}
2821
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002823 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002824 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002825 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002826 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002827 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002828 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002829 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002830 EXPECT_CALL(adm_,
2831 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2832 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2833 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002834 webrtc::AudioProcessing::Config apm_config;
2835 EXPECT_CALL(*apm_, GetConfig())
2836 .Times(10)
2837 .WillRepeatedly(ReturnPointee(&apm_config));
2838 EXPECT_CALL(*apm_, ApplyConfig(_))
2839 .Times(10)
2840 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002841 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002842
kwiberg686a8ef2016-02-26 03:00:35 -08002843 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002844 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002845 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002846 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002847 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002848 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849
2850 // Have to add a stream to make SetSend work.
2851 cricket::StreamParams stream1;
2852 stream1.ssrcs.push_back(1);
2853 channel1->AddSendStream(stream1);
2854 cricket::StreamParams stream2;
2855 stream2.ssrcs.push_back(2);
2856 channel2->AddSendStream(stream2);
2857
2858 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002859 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002860 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2861 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2862 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002863 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2864 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2865 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2866 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2867 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002868 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002869 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002870 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002872
2873 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002874 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002875 parameters_options_no_ns.options.noise_suppression =
2876 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002877 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2878 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2879 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2880 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2881 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002882 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002883 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002884 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2885 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2886 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002887 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002888
2889 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002890 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002891 parameters_options_no_agc.options.auto_gain_control =
2892 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002893 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2894 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2895 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2896 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2897 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002898 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002899 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2900 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2901 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002902 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002903
solenberg76377c52017-02-21 00:54:31 -08002904 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2905 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2906 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2908 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002909 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002916 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917
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(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002923 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002925 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002926 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2927 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002928 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002929 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002930 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002931 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002932 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2933 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2934 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2935 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2936 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002937 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002938 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2939 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2940 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002941 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942}
2943
wu@webrtc.orgde305012013-10-31 15:40:38 +00002944// This test verifies DSCP settings are properly applied on voice media channel.
2945TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002946 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002947 cricket::FakeNetworkInterface network_interface;
2948 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002949 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002950
peahb1c9d1d2017-07-25 15:45:24 -07002951 webrtc::AudioProcessing::Config apm_config;
2952 EXPECT_CALL(*apm_, GetConfig())
2953 .Times(3)
2954 .WillRepeatedly(ReturnPointee(&apm_config));
2955 EXPECT_CALL(*apm_, ApplyConfig(_))
2956 .Times(3)
2957 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002958 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002959
solenbergbc37fc82016-04-04 09:54:44 -07002960 channel.reset(
2961 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002962 channel->SetInterface(&network_interface);
2963 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2964 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2965
2966 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002967 channel.reset(
2968 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002969 channel->SetInterface(&network_interface);
2970 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2971
2972 // Verify that setting the option to false resets the
2973 // DiffServCodePoint.
2974 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002975 channel.reset(
2976 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002977 channel->SetInterface(&network_interface);
2978 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2979 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2980
2981 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002982}
2983
solenberg1ac56142015-10-13 03:58:19 -07002984TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002985 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986 cricket::WebRtcVoiceMediaChannel* media_channel =
2987 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002988 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002989 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002990 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002991 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2992 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2993 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002994 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002995 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996}
2997
solenberg1ac56142015-10-13 03:58:19 -07002998TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002999 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003001 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3002 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3003 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003004 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003005 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003006 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3007 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003008 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003009 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003010 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003011 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012}
3013
solenberg4bac9c52015-10-09 02:32:53 -07003014TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003015 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003016 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003017 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003018 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003019 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003020 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3021 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3022 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003023}
3024
solenberg2100c0b2017-03-01 11:29:29 -08003025TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003026 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003027
3028 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003029 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003030 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3031
3032 // Should remember the volume "2" which will be set on new unsignaled streams,
3033 // and also set the gain to 2 on existing unsignaled streams.
3034 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3035 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3036
3037 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3038 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3039 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3040 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3041 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3042 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3043
3044 // Setting gain with SSRC=0 should affect all unsignaled streams.
3045 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003046 if (kMaxUnsignaledRecvStreams > 1) {
3047 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3048 }
solenberg2100c0b2017-03-01 11:29:29 -08003049 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3050
3051 // Setting gain on an individual stream affects only that.
3052 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003053 if (kMaxUnsignaledRecvStreams > 1) {
3054 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3055 }
solenberg2100c0b2017-03-01 11:29:29 -08003056 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003057}
3058
pbos8fc7fa72015-07-15 08:02:58 -07003059TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003060 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003061 const std::string kSyncLabel = "AvSyncLabel";
3062
solenbergff976312016-03-30 23:28:51 -07003063 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003064 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3065 sp.sync_label = kSyncLabel;
3066 // Creating two channels to make sure that sync label is set properly for both
3067 // the default voice channel and following ones.
3068 EXPECT_TRUE(channel_->AddRecvStream(sp));
3069 sp.ssrcs[0] += 1;
3070 EXPECT_TRUE(channel_->AddRecvStream(sp));
3071
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003072 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003073 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003074 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003075 << "SyncGroup should be set based on sync_label";
3076 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003077 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003078 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003079}
3080
solenberg3a941542015-11-16 07:34:50 -08003081// TODO(solenberg): Remove, once recv streams are configured through Call.
3082// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003083TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003084 // Test that setting the header extensions results in the expected state
3085 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003086 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003087 ssrcs.push_back(223);
3088 ssrcs.push_back(224);
3089
solenbergff976312016-03-30 23:28:51 -07003090 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003091 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003092 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003093 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003094 cricket::StreamParams::CreateLegacy(ssrc)));
3095 }
3096
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003097 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003098 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003099 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003100 EXPECT_NE(nullptr, s);
3101 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3102 }
3103
3104 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003105 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003106 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003107 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003108 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003109 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003110 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003111 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 EXPECT_NE(nullptr, s);
3113 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003114 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3115 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003116 for (const auto& s_ext : s_exts) {
3117 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003118 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119 }
3120 }
3121 }
3122 }
3123
3124 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003125 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003126 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003127 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 EXPECT_NE(nullptr, s);
3129 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3130 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003131}
3132
3133TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3134 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003135 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003136 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003137 static const unsigned char kRtcp[] = {
3138 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3139 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3142 };
jbaucheec21bd2016-03-20 06:15:43 -07003143 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003144
solenbergff976312016-03-30 23:28:51 -07003145 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 cricket::WebRtcVoiceMediaChannel* media_channel =
3147 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003148 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003149 EXPECT_TRUE(media_channel->AddRecvStream(
3150 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3151
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003152 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003153 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003154 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003155 EXPECT_EQ(0, s->received_packets());
3156 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3157 EXPECT_EQ(1, s->received_packets());
3158 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3159 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003160}
Minyue2013aec2015-05-13 14:14:42 +02003161
solenberg0a617e22015-10-20 15:49:38 -07003162// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003163// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003164TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003165 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003166 EXPECT_TRUE(AddRecvStream(kSsrcY));
3167 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003168 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003169 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3170 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3171 EXPECT_TRUE(AddRecvStream(kSsrcW));
3172 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003173}
3174
solenberg7602aab2016-11-14 11:30:07 -08003175TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3176 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003177 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003178 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003179 cricket::StreamParams::CreateLegacy(kSsrcY)));
3180 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3181 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3182 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003183 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003184 cricket::StreamParams::CreateLegacy(kSsrcW)));
3185 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3186 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003187}
stefan658910c2015-09-03 05:48:32 -07003188
deadbeef884f5852016-01-15 09:20:04 -08003189TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003190 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003191 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3192 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003193
3194 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003195 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3196 EXPECT_TRUE(AddRecvStream(kSsrcX));
3197 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003198
3199 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003200 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3201 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003202
3203 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003204 channel_->SetRawAudioSink(kSsrcX, nullptr);
3205 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003206}
3207
solenberg2100c0b2017-03-01 11:29:29 -08003208TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003209 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003210 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3211 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003212 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3213 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003214
3215 // Should be able to set a default sink even when no stream exists.
3216 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3217
solenberg2100c0b2017-03-01 11:29:29 -08003218 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3219 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003220 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003221 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003222
3223 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003224 channel_->SetRawAudioSink(kSsrc0, nullptr);
3225 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003226
3227 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003228 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3229 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003230
3231 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003232 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003233 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003234 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3235
3236 // Spawn another unsignaled stream - it should be assigned the default sink
3237 // and the previous unsignaled stream should lose it.
3238 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3239 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3240 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3241 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
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 // Reset the default sink - the second unsignaled stream should lose it.
3248 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003249 if (kMaxUnsignaledRecvStreams > 1) {
3250 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3251 }
solenberg2100c0b2017-03-01 11:29:29 -08003252 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3253
3254 // Try setting the default sink while two streams exists.
3255 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003256 if (kMaxUnsignaledRecvStreams > 1) {
3257 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3258 }
solenberg2100c0b2017-03-01 11:29:29 -08003259 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3260
3261 // Try setting the sink for the first unsignaled stream using its known SSRC.
3262 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003263 if (kMaxUnsignaledRecvStreams > 1) {
3264 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3265 }
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003267 if (kMaxUnsignaledRecvStreams > 1) {
3268 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3269 }
deadbeef884f5852016-01-15 09:20:04 -08003270}
3271
skvlad7a43d252016-03-22 15:32:27 -07003272// Test that, just like the video channel, the voice channel communicates the
3273// network state to the call.
3274TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003275 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003276
3277 EXPECT_EQ(webrtc::kNetworkUp,
3278 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3279 EXPECT_EQ(webrtc::kNetworkUp,
3280 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3281
3282 channel_->OnReadyToSend(false);
3283 EXPECT_EQ(webrtc::kNetworkDown,
3284 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3285 EXPECT_EQ(webrtc::kNetworkUp,
3286 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3287
3288 channel_->OnReadyToSend(true);
3289 EXPECT_EQ(webrtc::kNetworkUp,
3290 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3291 EXPECT_EQ(webrtc::kNetworkUp,
3292 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3293}
3294
aleloi18e0b672016-10-04 02:45:47 -07003295// Test that playout is still started after changing parameters
3296TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3297 SetupRecvStream();
3298 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003299 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003300
3301 // Changing RTP header extensions will recreate the AudioReceiveStream.
3302 cricket::AudioRecvParameters parameters;
3303 parameters.extensions.push_back(
3304 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3305 channel_->SetRecvParameters(parameters);
3306
solenberg2100c0b2017-03-01 11:29:29 -08003307 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003308}
3309
stefan658910c2015-09-03 05:48:32 -07003310// Tests that the library initializes and shuts down properly.
3311TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003312 // If the VoiceEngine wants to gather available codecs early, that's fine but
3313 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003314 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003315 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3316 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003317 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003318 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003319 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003320 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003321 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003322 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003323 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003324 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3325 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003326 EXPECT_TRUE(channel != nullptr);
3327 delete channel;
solenbergff976312016-03-30 23:28:51 -07003328}
stefan658910c2015-09-03 05:48:32 -07003329
solenbergff976312016-03-30 23:28:51 -07003330// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003331TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3332 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003333 EXPECT_CALL(adm, AddRef()).Times(3);
3334 EXPECT_CALL(adm, Release())
3335 .Times(3)
3336 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003337 {
peaha9cc40b2017-06-29 08:32:09 -07003338 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3339 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003340 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003341 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003342 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003343 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003344 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003345 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003346 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003347 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3348 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3349 EXPECT_TRUE(channel != nullptr);
3350 delete channel;
3351 }
stefan658910c2015-09-03 05:48:32 -07003352}
3353
ossu20a4b3f2017-04-27 02:08:52 -07003354// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3355TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003356 // TODO(ossu): Why are the payload types of codecs with non-static payload
3357 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003358 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003359 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3360 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003361 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003362 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003363 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003364 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003365 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003366 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3367 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3368 (clockrate == 0 || codec.clockrate == clockrate);
3369 };
3370 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003371 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003372 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003373 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003374 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003375 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003376 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(126, codec.id);
3382 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3383 // Remove these checks once both send and receive side assigns payload types
3384 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003385 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003386 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003387 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003388 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003389 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003390 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003391 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003392 EXPECT_EQ(111, codec.id);
3393 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3394 EXPECT_EQ("10", codec.params.find("minptime")->second);
3395 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3396 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003397 }
3398 }
stefan658910c2015-09-03 05:48:32 -07003399}
3400
3401// Tests that VoE supports at least 32 channels
3402TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003403 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003404 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3405 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003406 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003407 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003408 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003409 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003410 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003411 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003412 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003413
3414 cricket::VoiceMediaChannel* channels[32];
3415 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003416 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003417 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3418 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003419 if (!channel)
3420 break;
stefan658910c2015-09-03 05:48:32 -07003421 channels[num_channels++] = channel;
3422 }
3423
tfarina5237aaf2015-11-10 23:44:30 -08003424 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003425 EXPECT_EQ(expected, num_channels);
3426
3427 while (num_channels > 0) {
3428 delete channels[--num_channels];
3429 }
stefan658910c2015-09-03 05:48:32 -07003430}
3431
3432// Test that we set our preferred codecs properly.
3433TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003434 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3435 // - Check that our builtin codecs are usable by Channel.
3436 // - The codecs provided by the engine is usable by Channel.
3437 // It does not check that the codecs in the RecvParameters are actually
3438 // what we sent in - though it's probably reasonable to expect so, if
3439 // SetRecvParameters returns true.
3440 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003441 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003442 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3443 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003444 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003445 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003446 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003447 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003448 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003449 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003450 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003451 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3452 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003453 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003454 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003455 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003456}
ossu9def8002017-02-09 05:14:32 -08003457
3458TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3459 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003460 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3461 {48000, 2, 16000, 10000, 20000}};
3462 spec1.info.allow_comfort_noise = false;
3463 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003464 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003465 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3466 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003467 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003468 specs.push_back(webrtc::AudioCodecSpec{
3469 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3470 {16000, 1, 13300}});
3471 specs.push_back(
3472 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3473 specs.push_back(
3474 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003475
ossueb1fde42017-05-02 06:46:30 -07003476 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3477 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3478 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003479 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003480 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003481 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003482 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003483
peaha9cc40b2017-06-29 08:32:09 -07003484 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3485 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003486 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003487 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003488 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003489 auto codecs = engine.recv_codecs();
3490 EXPECT_EQ(11, codecs.size());
3491
3492 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3493 // check the actual values safely, to provide better test results.
3494 auto get_codec =
3495 [&codecs](size_t index) -> const cricket::AudioCodec& {
3496 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3497 if (codecs.size() > index)
3498 return codecs[index];
3499 return missing_codec;
3500 };
3501
3502 // Ensure the general codecs are generated first and in order.
3503 for (size_t i = 0; i != specs.size(); ++i) {
3504 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3505 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3506 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3507 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3508 }
3509
3510 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003511 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003512 auto find_codec =
3513 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3514 for (size_t i = 0; i != codecs.size(); ++i) {
3515 const cricket::AudioCodec& codec = codecs[i];
3516 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3517 codec.clockrate == format.clockrate_hz &&
3518 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003519 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003520 }
3521 }
3522 return -1;
3523 };
3524
3525 // Ensure all supplementary codecs are generated last. Their internal ordering
3526 // is not important.
3527 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3528 const int num_specs = static_cast<int>(specs.size());
3529 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3530 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3531 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3532 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3533 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3534 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3535 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3536}