blob: f1782626d0eaed59052b33566705b318c0608cec [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);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010088
89 // Setup.
Niels Möller6f72f562017-10-19 13:15:17 +020090 EXPECT_CALL(*adm, AddRef()).Times(1);
Fredrik Solenbergd3195342017-11-21 20:33:05 +010091 EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -070092#if defined(WEBRTC_WIN)
93 EXPECT_CALL(*adm, SetPlayoutDevice(
94 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
95 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
96 .WillOnce(Return(0));
97#else
98 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
99#endif // #if defined(WEBRTC_WIN)
100 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
101 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
102 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100103#if defined(WEBRTC_WIN)
104 EXPECT_CALL(*adm, SetRecordingDevice(
105 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
106 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
107 .WillOnce(Return(0));
108#else
109 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
110#endif // #if defined(WEBRTC_WIN)
111 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
112 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
113 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
solenberg9a5f032222017-03-15 06:14:12 -0700114 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
116 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
117 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
Fredrik Solenbergd3195342017-11-21 20:33:05 +0100118
119 // Teardown.
120 EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
121 EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
122 EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
123 EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
124 EXPECT_CALL(*adm, Release())
125 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -0700126}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200127} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000128
solenbergff976312016-03-30 23:28:51 -0700129// Tests that our stub library "works".
130TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700131 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700132 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700133 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
134 new rtc::RefCountedObject<
135 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700136 webrtc::AudioProcessing::Config apm_config;
137 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
138 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700139 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
140 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
141 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800142 StrictMock<MockTransmitMixer> transmit_mixer;
143 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700144 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700145 EXPECT_FALSE(voe.IsInited());
146 {
ossuc54071d2016-08-17 02:45:41 -0700147 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700148 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700149 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700150 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700151 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700152 EXPECT_TRUE(voe.IsInited());
153 }
154 EXPECT_FALSE(voe.IsInited());
155}
156
deadbeef884f5852016-01-15 09:20:04 -0800157class FakeAudioSink : public webrtc::AudioSinkInterface {
158 public:
159 void OnData(const Data& audio) override {}
160};
161
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800162class FakeAudioSource : public cricket::AudioSource {
163 void SetSink(Sink* sink) override {}
164};
165
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166class WebRtcVoiceEngineTestFake : public testing::Test {
167 public:
stefanba4c0e42016-02-04 04:12:24 -0800168 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
169
170 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700171 : apm_(new rtc::RefCountedObject<
172 StrictMock<webrtc::test::MockAudioProcessing>>()),
173 apm_gc_(*apm_->gain_control()),
174 apm_ec_(*apm_->echo_cancellation()),
175 apm_ns_(*apm_->noise_suppression()),
176 apm_vd_(*apm_->voice_detection()),
177 call_(webrtc::Call::Config(&event_log_)),
178 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700179 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800180 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700181 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800182 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700183 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
184 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700185 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
186 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
187 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800188 // Default Options.
189 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
190 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
191 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
192 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
193 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
194 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
195 // Init does not overwrite default AGC config.
196 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
197 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
198 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
199 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
200 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
201 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700202 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800203 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700204 // factories. Those tests should probably be moved elsewhere.
205 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
206 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
207 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700208 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700209 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700210 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200211 send_parameters_.codecs.push_back(kPcmuCodec);
212 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800213 // Default Options.
214 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215 }
solenberg8189b022016-06-14 12:13:00 -0700216
solenbergff976312016-03-30 23:28:51 -0700217 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700218 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700219 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
220 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200221 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000222 }
solenberg8189b022016-06-14 12:13:00 -0700223
solenbergff976312016-03-30 23:28:51 -0700224 bool SetupRecvStream() {
225 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700226 return false;
227 }
solenberg2100c0b2017-03-01 11:29:29 -0800228 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700229 }
solenberg8189b022016-06-14 12:13:00 -0700230
solenbergff976312016-03-30 23:28:51 -0700231 bool SetupSendStream() {
232 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000233 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 }
solenberg2100c0b2017-03-01 11:29:29 -0800235 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800236 return false;
237 }
peaha9cc40b2017-06-29 08:32:09 -0700238 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800239 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
solenberg8189b022016-06-14 12:13:00 -0700241
242 bool AddRecvStream(uint32_t ssrc) {
243 EXPECT_TRUE(channel_);
244 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
245 }
246
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000247 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700248 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700249 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800250 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
251 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700252 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800253 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254 }
solenberg8189b022016-06-14 12:13:00 -0700255
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700257 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000258 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 }
solenberg8189b022016-06-14 12:13:00 -0700260
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200261 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 }
264
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100265 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
266 const auto* send_stream = call_.GetAudioSendStream(ssrc);
267 EXPECT_TRUE(send_stream);
268 return *send_stream;
269 }
270
deadbeef884f5852016-01-15 09:20:04 -0800271 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
272 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
273 EXPECT_TRUE(recv_stream);
274 return *recv_stream;
275 }
276
solenberg3a941542015-11-16 07:34:50 -0800277 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800278 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800279 }
280
solenberg7add0582015-11-20 09:59:34 -0800281 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800282 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800283 }
284
solenberg059fb442016-10-26 05:12:24 -0700285 void SetSend(bool enable) {
286 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700287 if (enable) {
288 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
289 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
290 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700291 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700292 }
solenberg059fb442016-10-26 05:12:24 -0700293 channel_->SetSend(enable);
294 }
295
296 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700297 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700298 ASSERT_TRUE(channel_);
299 EXPECT_TRUE(channel_->SetSendParameters(params));
300 }
301
minyue6b825df2016-10-31 04:08:32 -0700302 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
303 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700304 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700305 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700306 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700307 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700308 }
309 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700310 }
311
solenbergffbbcac2016-11-17 05:25:37 -0800312 void TestInsertDtmf(uint32_t ssrc, bool caller,
313 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700314 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000315 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700316 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 // send stream.
318 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800319 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000320 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000321
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700323 SetSendParameters(send_parameters_);
324 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800327 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700328 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000330
331 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700332 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800333 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000334 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800335 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000336 }
337
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000338 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800339 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 // Test send.
342 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800343 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100344 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800345 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800346 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800347 EXPECT_EQ(codec.id, telephone_event.payload_type);
348 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100349 EXPECT_EQ(2, telephone_event.event_code);
350 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 }
352
353 // Test that send bandwidth is set correctly.
354 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000355 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
356 // |expected_result| is the expected result from SetMaxSendBandwidth().
357 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700358 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
359 int max_bitrate,
360 bool expected_result,
361 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200362 cricket::AudioSendParameters parameters;
363 parameters.codecs.push_back(codec);
364 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700365 if (expected_result) {
366 SetSendParameters(parameters);
367 } else {
368 EXPECT_FALSE(channel_->SetSendParameters(parameters));
369 }
solenberg2100c0b2017-03-01 11:29:29 -0800370 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371 }
372
skvlade0d46372016-04-07 22:59:22 -0700373 // Sets the per-stream maximum bitrate limit for the specified SSRC.
374 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700375 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700376 EXPECT_EQ(1UL, parameters.encodings.size());
377
Oskar Sundbom78807582017-11-16 11:09:55 +0100378 parameters.encodings[0].max_bitrate_bps = bitrate;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700379 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700380 }
381
solenberg059fb442016-10-26 05:12:24 -0700382 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700383 cricket::AudioSendParameters send_parameters;
384 send_parameters.codecs.push_back(codec);
385 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700386 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700387 }
388
ossu20a4b3f2017-04-27 02:08:52 -0700389 void CheckSendCodecBitrate(int32_t ssrc,
390 const char expected_name[],
391 int expected_bitrate) {
392 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
393 EXPECT_EQ(expected_name, spec->format.name);
394 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700395 }
396
ossu20a4b3f2017-04-27 02:08:52 -0700397 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
398 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700399 }
400
minyue6b825df2016-10-31 04:08:32 -0700401 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
402 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
403 }
404
skvlade0d46372016-04-07 22:59:22 -0700405 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
406 int global_max,
407 int stream_max,
408 bool expected_result,
409 int expected_codec_bitrate) {
410 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800411 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700412
413 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700414 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800415 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700416
417 // Verify that reading back the parameters gives results
418 // consistent with the Set() result.
419 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800420 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700421 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
422 EXPECT_EQ(expected_result ? stream_max : -1,
423 resulting_parameters.encodings[0].max_bitrate_bps);
424
425 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800426 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700427 }
428
stefan13f1a0a2016-11-30 07:22:58 -0800429 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
430 int expected_min_bitrate_bps,
431 const char* start_bitrate_kbps,
432 int expected_start_bitrate_bps,
433 const char* max_bitrate_kbps,
434 int expected_max_bitrate_bps) {
435 EXPECT_TRUE(SetupSendStream());
436 auto& codecs = send_parameters_.codecs;
437 codecs.clear();
438 codecs.push_back(kOpusCodec);
439 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
440 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
441 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
442 SetSendParameters(send_parameters_);
443
444 EXPECT_EQ(expected_min_bitrate_bps,
445 call_.GetConfig().bitrate_config.min_bitrate_bps);
446 EXPECT_EQ(expected_start_bitrate_bps,
447 call_.GetConfig().bitrate_config.start_bitrate_bps);
448 EXPECT_EQ(expected_max_bitrate_bps,
449 call_.GetConfig().bitrate_config.max_bitrate_bps);
450 }
451
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000452 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700453 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000454
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000455 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
458 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700459 send_parameters_.extensions.push_back(
460 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
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
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000464 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200465 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000468
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000469 // Ensure extension is set properly.
470 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700471 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700472 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800473 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
474 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
475 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000476
solenberg7add0582015-11-20 09:59:34 -0800477 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000478 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800479 cricket::StreamParams::CreateLegacy(kSsrcY)));
480 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
481 call_.GetAudioSendStream(kSsrcY));
482 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
483 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
484 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485
486 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200487 send_parameters_.codecs.push_back(kPcmuCodec);
488 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700489 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800490 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
491 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492 }
493
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000494 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700495 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000497 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
500 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700501 recv_parameters_.extensions.push_back(
502 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800503 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 extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800507 recv_parameters_.extensions.clear();
508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000510
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000511 // Ensure extension is set properly.
512 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700513 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800514 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800515 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
516 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
517 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000518
solenberg7add0582015-11-20 09:59:34 -0800519 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800520 EXPECT_TRUE(AddRecvStream(kSsrcY));
521 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
522 call_.GetAudioReceiveStream(kSsrcY));
523 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
524 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
525 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000526
527 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800528 recv_parameters_.extensions.clear();
529 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800530 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
531 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000532 }
533
solenberg85a04962015-10-27 03:35:21 -0700534 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
535 webrtc::AudioSendStream::Stats stats;
536 stats.local_ssrc = 12;
537 stats.bytes_sent = 345;
538 stats.packets_sent = 678;
539 stats.packets_lost = 9012;
540 stats.fraction_lost = 34.56f;
541 stats.codec_name = "codec_name_send";
Oskar Sundbom78807582017-11-16 11:09:55 +0100542 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700543 stats.ext_seqnum = 789;
544 stats.jitter_ms = 12;
545 stats.rtt_ms = 345;
546 stats.audio_level = 678;
547 stats.aec_quality_min = 9.01f;
548 stats.echo_delay_median_ms = 234;
549 stats.echo_delay_std_ms = 567;
550 stats.echo_return_loss = 890;
551 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700552 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800553 stats.residual_echo_likelihood_recent_max = 0.6f;
Oskar Sundbom78807582017-11-16 11:09:55 +0100554 stats.ana_statistics.bitrate_action_counter = 321;
555 stats.ana_statistics.channel_action_counter = 432;
556 stats.ana_statistics.dtx_action_counter = 543;
557 stats.ana_statistics.fec_action_counter = 654;
558 stats.ana_statistics.frame_length_increase_counter = 765;
559 stats.ana_statistics.frame_length_decrease_counter = 876;
560 stats.ana_statistics.uplink_packet_loss_fraction = 987.0;
solenberg85a04962015-10-27 03:35:21 -0700561 stats.typing_noise_detected = true;
562 return stats;
563 }
564 void SetAudioSendStreamStats() {
565 for (auto* s : call_.GetAudioSendStreams()) {
566 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200567 }
solenberg85a04962015-10-27 03:35:21 -0700568 }
solenberg566ef242015-11-06 15:34:49 -0800569 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
570 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700571 const auto stats = GetAudioSendStreamStats();
572 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
573 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
574 EXPECT_EQ(info.packets_sent, stats.packets_sent);
575 EXPECT_EQ(info.packets_lost, stats.packets_lost);
576 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
577 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800578 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700579 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
580 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
581 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
582 EXPECT_EQ(info.audio_level, stats.audio_level);
583 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
584 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
585 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
586 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
587 EXPECT_EQ(info.echo_return_loss_enhancement,
588 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700589 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800590 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
591 stats.residual_echo_likelihood_recent_max);
ivoce1198e02017-09-08 08:13:19 -0700592 EXPECT_EQ(info.ana_statistics.bitrate_action_counter,
593 stats.ana_statistics.bitrate_action_counter);
594 EXPECT_EQ(info.ana_statistics.channel_action_counter,
595 stats.ana_statistics.channel_action_counter);
596 EXPECT_EQ(info.ana_statistics.dtx_action_counter,
597 stats.ana_statistics.dtx_action_counter);
598 EXPECT_EQ(info.ana_statistics.fec_action_counter,
599 stats.ana_statistics.fec_action_counter);
ivoc0d0b9122017-09-08 13:24:21 -0700600 EXPECT_EQ(info.ana_statistics.frame_length_increase_counter,
601 stats.ana_statistics.frame_length_increase_counter);
602 EXPECT_EQ(info.ana_statistics.frame_length_decrease_counter,
603 stats.ana_statistics.frame_length_decrease_counter);
604 EXPECT_EQ(info.ana_statistics.uplink_packet_loss_fraction,
605 stats.ana_statistics.uplink_packet_loss_fraction);
solenberg566ef242015-11-06 15:34:49 -0800606 EXPECT_EQ(info.typing_noise_detected,
607 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700608 }
609
610 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
611 webrtc::AudioReceiveStream::Stats stats;
612 stats.remote_ssrc = 123;
613 stats.bytes_rcvd = 456;
614 stats.packets_rcvd = 768;
615 stats.packets_lost = 101;
616 stats.fraction_lost = 23.45f;
617 stats.codec_name = "codec_name_recv";
Oskar Sundbom78807582017-11-16 11:09:55 +0100618 stats.codec_payload_type = 42;
solenberg85a04962015-10-27 03:35:21 -0700619 stats.ext_seqnum = 678;
620 stats.jitter_ms = 901;
621 stats.jitter_buffer_ms = 234;
622 stats.jitter_buffer_preferred_ms = 567;
623 stats.delay_estimate_ms = 890;
624 stats.audio_level = 1234;
Steve Anton2dbc69f2017-08-24 17:15:13 -0700625 stats.total_samples_received = 5678901;
626 stats.concealed_samples = 234;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200627 stats.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200628 stats.jitter_buffer_delay_seconds = 34;
solenberg85a04962015-10-27 03:35:21 -0700629 stats.expand_rate = 5.67f;
630 stats.speech_expand_rate = 8.90f;
631 stats.secondary_decoded_rate = 1.23f;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200632 stats.secondary_discarded_rate = 0.12f;
solenberg85a04962015-10-27 03:35:21 -0700633 stats.accelerate_rate = 4.56f;
634 stats.preemptive_expand_rate = 7.89f;
635 stats.decoding_calls_to_silence_generator = 12;
636 stats.decoding_calls_to_neteq = 345;
637 stats.decoding_normal = 67890;
638 stats.decoding_plc = 1234;
639 stats.decoding_cng = 5678;
640 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700641 stats.decoding_muted_output = 3456;
642 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200643 return stats;
644 }
645 void SetAudioReceiveStreamStats() {
646 for (auto* s : call_.GetAudioReceiveStreams()) {
647 s->SetStats(GetAudioReceiveStreamStats());
648 }
649 }
650 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700651 const auto stats = GetAudioReceiveStreamStats();
652 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
653 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
654 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
655 EXPECT_EQ(info.packets_lost, stats.packets_lost);
656 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
657 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800658 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700659 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
660 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
661 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200662 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700663 stats.jitter_buffer_preferred_ms);
664 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
665 EXPECT_EQ(info.audio_level, stats.audio_level);
Steve Anton2dbc69f2017-08-24 17:15:13 -0700666 EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
667 EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200668 EXPECT_EQ(info.concealment_events, stats.concealment_events);
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200669 EXPECT_EQ(info.jitter_buffer_delay_seconds,
670 stats.jitter_buffer_delay_seconds);
solenberg85a04962015-10-27 03:35:21 -0700671 EXPECT_EQ(info.expand_rate, stats.expand_rate);
672 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
673 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200674 EXPECT_EQ(info.secondary_discarded_rate, stats.secondary_discarded_rate);
solenberg85a04962015-10-27 03:35:21 -0700675 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
676 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200677 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700678 stats.decoding_calls_to_silence_generator);
679 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
680 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
681 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
682 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
683 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700684 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700685 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200686 }
hbos1acfbd22016-11-17 23:43:29 -0800687 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
688 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
689 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
690 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
691 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
692 codec.ToCodecParameters());
693 }
694 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
695 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
696 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
697 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
698 codec.ToCodecParameters());
699 }
700 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200701
peah8271d042016-11-22 07:24:52 -0800702 bool IsHighPassFilterEnabled() {
703 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
704 }
705
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700707 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700708 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800709 webrtc::test::MockGainControl& apm_gc_;
710 webrtc::test::MockEchoCancellation& apm_ec_;
711 webrtc::test::MockNoiseSuppression& apm_ns_;
712 webrtc::test::MockVoiceDetection& apm_vd_;
713 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700714 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200715 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700717 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700718 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200719 cricket::AudioSendParameters send_parameters_;
720 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800721 FakeAudioSource fake_source_;
peahb1c9d1d2017-07-25 15:45:24 -0700722 webrtc::AudioProcessing::Config apm_config_;
723
stefanba4c0e42016-02-04 04:12:24 -0800724 private:
725 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726};
727
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728// Tests that we can create and destroy a channel.
729TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700730 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731}
732
solenberg31fec402016-05-06 02:13:12 -0700733// Test that we can add a send stream and that it has the correct defaults.
734TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
735 EXPECT_TRUE(SetupChannel());
736 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800737 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
738 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
739 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700740 EXPECT_EQ("", config.rtp.c_name);
741 EXPECT_EQ(0u, config.rtp.extensions.size());
742 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
743 config.send_transport);
744}
745
746// Test that we can add a receive stream and that it has the correct defaults.
747TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
748 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800749 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700750 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800751 GetRecvStreamConfig(kSsrcX);
752 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700753 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
754 EXPECT_FALSE(config.rtp.transport_cc);
755 EXPECT_EQ(0u, config.rtp.extensions.size());
756 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
757 config.rtcp_send_transport);
758 EXPECT_EQ("", config.sync_group);
759}
760
stefanba4c0e42016-02-04 04:12:24 -0800761TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700762 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800763 bool opus_found = false;
764 for (cricket::AudioCodec codec : codecs) {
765 if (codec.name == "opus") {
766 EXPECT_TRUE(HasTransportCc(codec));
767 opus_found = true;
768 }
769 }
770 EXPECT_TRUE(opus_found);
771}
772
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773// Test that we set our inbound codecs properly, including changing PT.
774TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700775 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200776 cricket::AudioRecvParameters parameters;
777 parameters.codecs.push_back(kIsacCodec);
778 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800779 parameters.codecs.push_back(kTelephoneEventCodec1);
780 parameters.codecs.push_back(kTelephoneEventCodec2);
781 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200782 parameters.codecs[2].id = 126;
783 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800784 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700785 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
786 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
787 {{0, {"PCMU", 8000, 1}},
788 {106, {"ISAC", 16000, 1}},
789 {126, {"telephone-event", 8000, 1}},
790 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791}
792
793// Test that we fail to set an unknown inbound codec.
794TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700795 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 cricket::AudioRecvParameters parameters;
797 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700798 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200799 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800}
801
802// Test that we fail if we have duplicate types in the inbound list.
803TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700804 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200805 cricket::AudioRecvParameters parameters;
806 parameters.codecs.push_back(kIsacCodec);
807 parameters.codecs.push_back(kCn16000Codec);
808 parameters.codecs[1].id = kIsacCodec.id;
809 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810}
811
812// Test that we can decode OPUS without stereo parameters.
813TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700814 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200815 cricket::AudioRecvParameters parameters;
816 parameters.codecs.push_back(kIsacCodec);
817 parameters.codecs.push_back(kPcmuCodec);
818 parameters.codecs.push_back(kOpusCodec);
819 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800820 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700821 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
822 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
823 {{0, {"PCMU", 8000, 1}},
824 {103, {"ISAC", 16000, 1}},
825 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826}
827
828// Test that we can decode OPUS with stereo = 0.
829TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700830 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200831 cricket::AudioRecvParameters parameters;
832 parameters.codecs.push_back(kIsacCodec);
833 parameters.codecs.push_back(kPcmuCodec);
834 parameters.codecs.push_back(kOpusCodec);
835 parameters.codecs[2].params["stereo"] = "0";
836 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800837 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700838 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
839 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
840 {{0, {"PCMU", 8000, 1}},
841 {103, {"ISAC", 16000, 1}},
842 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843}
844
845// Test that we can decode OPUS with stereo = 1.
846TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700847 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200848 cricket::AudioRecvParameters parameters;
849 parameters.codecs.push_back(kIsacCodec);
850 parameters.codecs.push_back(kPcmuCodec);
851 parameters.codecs.push_back(kOpusCodec);
852 parameters.codecs[2].params["stereo"] = "1";
853 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800854 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700855 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
856 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
857 {{0, {"PCMU", 8000, 1}},
858 {103, {"ISAC", 16000, 1}},
859 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860}
861
862// Test that changes to recv codecs are applied to all streams.
863TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700864 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200865 cricket::AudioRecvParameters parameters;
866 parameters.codecs.push_back(kIsacCodec);
867 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800868 parameters.codecs.push_back(kTelephoneEventCodec1);
869 parameters.codecs.push_back(kTelephoneEventCodec2);
870 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200871 parameters.codecs[2].id = 126;
872 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700873 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
874 EXPECT_TRUE(AddRecvStream(ssrc));
875 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
876 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
877 {{0, {"PCMU", 8000, 1}},
878 {106, {"ISAC", 16000, 1}},
879 {126, {"telephone-event", 8000, 1}},
880 {107, {"telephone-event", 32000, 1}}})));
881 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882}
883
884TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700885 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200886 cricket::AudioRecvParameters parameters;
887 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800888 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200889 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
solenberg2100c0b2017-03-01 11:29:29 -0800891 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800892 ASSERT_EQ(1, dm.count(106));
893 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894}
895
896// Test that we can apply the same set of codecs again while playing.
897TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700898 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 cricket::AudioRecvParameters parameters;
900 parameters.codecs.push_back(kIsacCodec);
901 parameters.codecs.push_back(kCn16000Codec);
902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700903 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200904 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905
deadbeefcb383672017-04-26 16:28:42 -0700906 // Remapping a payload type to a different codec should fail.
907 parameters.codecs[0] = kOpusCodec;
908 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200909 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800910 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911}
912
913// Test that we can add a codec while playing.
914TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700915 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200916 cricket::AudioRecvParameters parameters;
917 parameters.codecs.push_back(kIsacCodec);
918 parameters.codecs.push_back(kCn16000Codec);
919 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700920 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 parameters.codecs.push_back(kOpusCodec);
923 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800924 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925}
926
deadbeefcb383672017-04-26 16:28:42 -0700927// Test that we accept adding the same codec with a different payload type.
928// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
929TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
930 EXPECT_TRUE(SetupRecvStream());
931 cricket::AudioRecvParameters parameters;
932 parameters.codecs.push_back(kIsacCodec);
933 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
934
935 ++parameters.codecs[0].id;
936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
937}
938
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700940 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000942 // Test that when autobw is enabled, bitrate is kept as the default
943 // value. autobw is enabled for the following tests because the target
944 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
946 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700947 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
949 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700950 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
ossu20a4b3f2017-04-27 02:08:52 -0700952 // opus, default bitrate == 32000 in mono.
953 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954}
955
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000956TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700957 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700960 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
961 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700962 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700965 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
966 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
967 // Rates above the max (510000) should be capped.
968 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969}
970
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000971TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700972 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000973
974 // Test that we can only set a maximum bitrate for a fixed-rate codec
975 // if it's bigger than the fixed rate.
976
977 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700978 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
979 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
980 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
981 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
982 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
983 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
984 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000985}
986
987TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700988 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200989 const int kDesiredBitrate = 128000;
990 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700991 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200992 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700993 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000994
995 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800996 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000997
solenberg2100c0b2017-03-01 11:29:29 -0800998 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000999}
1000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001// Test that bitrate cannot be set for CBR codecs.
1002// Bitrate is ignored if it is higher than the fixed bitrate.
1003// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001004TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001005 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001006
1007 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001008 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001009 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001010
1011 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001012 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001013 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001014
1015 send_parameters_.max_bandwidth_bps = 128;
1016 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001017 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018}
1019
skvlade0d46372016-04-07 22:59:22 -07001020// Test that the per-stream bitrate limit and the global
1021// bitrate limit both apply.
1022TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1023 EXPECT_TRUE(SetupSendStream());
1024
ossu20a4b3f2017-04-27 02:08:52 -07001025 // opus, default bitrate == 32000.
1026 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -07001027 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1028 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1029 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1030
1031 // CBR codecs allow both maximums to exceed the bitrate.
1032 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1033 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1034 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1035 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1036
1037 // CBR codecs don't allow per stream maximums to be too low.
1038 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1039 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1040}
1041
1042// Test that an attempt to set RtpParameters for a stream that does not exist
1043// fails.
1044TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1045 EXPECT_TRUE(SetupChannel());
1046 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001047 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001048 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1049
1050 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001051 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001052}
1053
1054TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001055 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001056 // This test verifies that setting RtpParameters succeeds only if
1057 // the structure contains exactly one encoding.
1058 // TODO(skvlad): Update this test when we start supporting setting parameters
1059 // for each encoding individually.
1060
1061 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001062 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001063 // Two or more encodings should result in failure.
1064 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001065 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001066 // Zero encodings should also fail.
1067 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001068 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001069}
1070
1071// Changing the SSRC through RtpParameters is not allowed.
1072TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1073 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001074 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Oskar Sundbom78807582017-11-16 11:09:55 +01001075 parameters.encodings[0].ssrc = 0xdeadbeef;
solenberg2100c0b2017-03-01 11:29:29 -08001076 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001077}
1078
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001079// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001080// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001081TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1082 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001083 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001084 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001086 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087 ASSERT_EQ(1u, parameters.encodings.size());
1088 ASSERT_TRUE(parameters.encodings[0].active);
1089 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1091 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001092
1093 // Now change it back to active and verify we resume sending.
1094 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001095 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1096 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001097}
1098
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001099// Test that SetRtpSendParameters configures the correct encoding channel for
1100// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001101TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1102 SetupForMultiSendStream();
1103 // Create send streams.
1104 for (uint32_t ssrc : kSsrcs4) {
1105 EXPECT_TRUE(
1106 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1107 }
1108 // Configure one stream to be limited by the stream config, another to be
1109 // limited by the global max, and the third one with no per-stream limit
1110 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001111 SetGlobalMaxBitrate(kOpusCodec, 32000);
1112 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1113 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001114 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1115
ossu20a4b3f2017-04-27 02:08:52 -07001116 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1117 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1118 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001119
1120 // Remove the global cap; the streams should switch to their respective
1121 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001122 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001123 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1124 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1125 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001126}
1127
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001128// Test that GetRtpSendParameters returns the currently configured codecs.
1129TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001130 EXPECT_TRUE(SetupSendStream());
1131 cricket::AudioSendParameters parameters;
1132 parameters.codecs.push_back(kIsacCodec);
1133 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001134 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001135
solenberg2100c0b2017-03-01 11:29:29 -08001136 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001137 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001138 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1139 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001140}
1141
deadbeefcb443432016-12-12 11:12:36 -08001142// Test that GetRtpSendParameters returns an SSRC.
1143TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1144 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001145 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001146 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001147 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001148}
1149
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001151TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001152 EXPECT_TRUE(SetupSendStream());
1153 cricket::AudioSendParameters parameters;
1154 parameters.codecs.push_back(kIsacCodec);
1155 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001156 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157
solenberg2100c0b2017-03-01 11:29:29 -08001158 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001159
1160 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001161 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001162
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001163 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001164 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1165 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001166}
1167
minyuececec102017-03-27 13:04:25 -07001168// Test that max_bitrate_bps in send stream config gets updated correctly when
1169// SetRtpSendParameters is called.
1170TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1171 webrtc::test::ScopedFieldTrials override_field_trials(
1172 "WebRTC-Audio-SendSideBwe/Enabled/");
1173 EXPECT_TRUE(SetupSendStream());
1174 cricket::AudioSendParameters send_parameters;
1175 send_parameters.codecs.push_back(kOpusCodec);
1176 SetSendParameters(send_parameters);
1177
1178 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1179 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1180 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1181
1182 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01001183 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07001184 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1185
1186 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1187 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1188}
1189
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001190// Test that GetRtpReceiveParameters returns the currently configured codecs.
1191TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1192 EXPECT_TRUE(SetupRecvStream());
1193 cricket::AudioRecvParameters parameters;
1194 parameters.codecs.push_back(kIsacCodec);
1195 parameters.codecs.push_back(kPcmuCodec);
1196 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1197
1198 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001199 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001200 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1201 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1202 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1203}
1204
deadbeefcb443432016-12-12 11:12:36 -08001205// Test that GetRtpReceiveParameters returns an SSRC.
1206TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1207 EXPECT_TRUE(SetupRecvStream());
1208 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001209 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001210 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001211 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001212}
1213
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001214// Test that if we set/get parameters multiple times, we get the same results.
1215TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1216 EXPECT_TRUE(SetupRecvStream());
1217 cricket::AudioRecvParameters parameters;
1218 parameters.codecs.push_back(kIsacCodec);
1219 parameters.codecs.push_back(kPcmuCodec);
1220 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1221
1222 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001223 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001224
1225 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001226 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001227
1228 // ... And this shouldn't change the params returned by
1229 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001230 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1231 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001232}
1233
deadbeef3bc15102017-04-20 19:25:07 -07001234// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1235// aren't signaled. It should return an empty "RtpEncodingParameters" when
1236// configured to receive an unsignaled stream and no packets have been received
1237// yet, and start returning the SSRC once a packet has been received.
1238TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1239 ASSERT_TRUE(SetupChannel());
1240 // Call necessary methods to configure receiving a default stream as
1241 // soon as it arrives.
1242 cricket::AudioRecvParameters parameters;
1243 parameters.codecs.push_back(kIsacCodec);
1244 parameters.codecs.push_back(kPcmuCodec);
1245 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1246
1247 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1248 // stream. Should return nothing.
1249 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1250
1251 // Set a sink for an unsignaled stream.
1252 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1253 // Value of "0" means "unsignaled stream".
1254 channel_->SetRawAudioSink(0, std::move(fake_sink));
1255
1256 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1257 // in this method means "unsignaled stream".
1258 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1259 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1260 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1261
1262 // Receive PCMU packet (SSRC=1).
1263 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1264
1265 // The |ssrc| member should still be unset.
1266 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1267 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1268 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1269}
1270
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001271// Test that we apply codecs properly.
1272TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001273 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001274 cricket::AudioSendParameters parameters;
1275 parameters.codecs.push_back(kIsacCodec);
1276 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001277 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001278 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001279 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001280 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001281 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1282 EXPECT_EQ(96, send_codec_spec.payload_type);
1283 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1284 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1285 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
Oskar Sundbom78807582017-11-16 11:09:55 +01001286 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001287 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001288}
1289
ossu20a4b3f2017-04-27 02:08:52 -07001290// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1291// AudioSendStream.
1292TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001293 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kIsacCodec);
1296 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001297 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 parameters.codecs[0].id = 96;
1299 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001300 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001301 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001302 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001303 // Calling SetSendCodec again with same codec which is already set.
1304 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001305 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001306 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001307}
1308
ossu20a4b3f2017-04-27 02:08:52 -07001309// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1310// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001311
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001312// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001314 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001315 cricket::AudioSendParameters parameters;
1316 parameters.codecs.push_back(kOpusCodec);
1317 parameters.codecs[0].bitrate = 0;
1318 parameters.codecs[0].clockrate = 50000;
1319 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001320}
1321
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001322// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001324 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001325 cricket::AudioSendParameters parameters;
1326 parameters.codecs.push_back(kOpusCodec);
1327 parameters.codecs[0].bitrate = 0;
1328 parameters.codecs[0].channels = 0;
1329 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330}
1331
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001332// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001334 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001335 cricket::AudioSendParameters parameters;
1336 parameters.codecs.push_back(kOpusCodec);
1337 parameters.codecs[0].bitrate = 0;
1338 parameters.codecs[0].channels = 0;
1339 parameters.codecs[0].params["stereo"] = "1";
1340 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341}
1342
1343// Test that if channel is 1 for opus and there's no stereo, we fail.
1344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kOpusCodec);
1348 parameters.codecs[0].bitrate = 0;
1349 parameters.codecs[0].channels = 1;
1350 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351}
1352
1353// Test that if channel is 1 for opus and stereo=0, we fail.
1354TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001355 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001356 cricket::AudioSendParameters parameters;
1357 parameters.codecs.push_back(kOpusCodec);
1358 parameters.codecs[0].bitrate = 0;
1359 parameters.codecs[0].channels = 1;
1360 parameters.codecs[0].params["stereo"] = "0";
1361 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
1364// Test that if channel is 1 for opus and stereo=1, we fail.
1365TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001366 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 cricket::AudioSendParameters parameters;
1368 parameters.codecs.push_back(kOpusCodec);
1369 parameters.codecs[0].bitrate = 0;
1370 parameters.codecs[0].channels = 1;
1371 parameters.codecs[0].params["stereo"] = "1";
1372 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001373}
1374
ossu20a4b3f2017-04-27 02:08:52 -07001375// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001377 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 cricket::AudioSendParameters parameters;
1379 parameters.codecs.push_back(kOpusCodec);
1380 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001381 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001382 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383}
1384
ossu20a4b3f2017-04-27 02:08:52 -07001385// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001387 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 cricket::AudioSendParameters parameters;
1389 parameters.codecs.push_back(kOpusCodec);
1390 parameters.codecs[0].bitrate = 0;
1391 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001392 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001393 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001394}
1395
ossu20a4b3f2017-04-27 02:08:52 -07001396// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001398 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 cricket::AudioSendParameters parameters;
1400 parameters.codecs.push_back(kOpusCodec);
1401 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001402 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001404 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001405 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001406
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001408 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001409 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410}
1411
ossu20a4b3f2017-04-27 02:08:52 -07001412// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001414 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kOpusCodec);
1417 parameters.codecs[0].bitrate = 0;
1418 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001419 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001420 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001421}
1422
ossu20a4b3f2017-04-27 02:08:52 -07001423// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001424TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001425 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001426 cricket::AudioSendParameters parameters;
1427 parameters.codecs.push_back(kOpusCodec);
1428 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001429 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001433
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001434 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001435 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001436 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001437}
1438
ossu20a4b3f2017-04-27 02:08:52 -07001439// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001441 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001442 cricket::AudioSendParameters parameters;
1443 parameters.codecs.push_back(kOpusCodec);
1444 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001445 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001446 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1447 EXPECT_EQ(111, spec.payload_type);
1448 EXPECT_EQ(96000, spec.target_bitrate_bps);
1449 EXPECT_EQ("opus", spec.format.name);
1450 EXPECT_EQ(2, spec.format.num_channels);
1451 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452}
1453
ossu20a4b3f2017-04-27 02:08:52 -07001454// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 30000;
1460 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001461 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001462 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
ossu20a4b3f2017-04-27 02:08:52 -07001465// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001471 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001472 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
ossu20a4b3f2017-04-27 02:08:52 -07001475// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001477 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001478 cricket::AudioSendParameters parameters;
1479 parameters.codecs.push_back(kOpusCodec);
1480 parameters.codecs[0].bitrate = 30000;
1481 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001483 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484}
1485
stefan13f1a0a2016-11-30 07:22:58 -08001486TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1487 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1488 200000);
1489}
1490
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1492 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake,
1496 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1497 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1498}
1499
1500TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1501 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001505 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001506 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1507 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001508 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001509 SetSendParameters(send_parameters_);
1510 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1511 << "Setting max bitrate should keep previous min bitrate.";
1512 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1513 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001514 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001515}
1516
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001517// Test that we can enable NACK with opus as caller.
1518TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001519 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001520 cricket::AudioSendParameters parameters;
1521 parameters.codecs.push_back(kOpusCodec);
1522 parameters.codecs[0].AddFeedbackParam(
1523 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1524 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001525 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001526 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528}
1529
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001530// Test that we can enable NACK with opus as callee.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001540 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001541 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001542
1543 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001544 cricket::StreamParams::CreateLegacy(kSsrcX)));
1545 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001546}
1547
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548// Test that we can enable NACK on receive streams.
1549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001550 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001552 cricket::AudioSendParameters parameters;
1553 parameters.codecs.push_back(kOpusCodec);
1554 parameters.codecs[0].AddFeedbackParam(
1555 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1556 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001557 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1558 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001559 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001560 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1561 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
1564// Test that we can disable NACK.
1565TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001566 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::AudioSendParameters parameters;
1568 parameters.codecs.push_back(kOpusCodec);
1569 parameters.codecs[0].AddFeedbackParam(
1570 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1571 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 parameters.codecs.clear();
1576 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001577 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001578 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579}
1580
1581// Test that we can disable NACK on receive streams.
1582TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001583 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001584 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001585 cricket::AudioSendParameters parameters;
1586 parameters.codecs.push_back(kOpusCodec);
1587 parameters.codecs[0].AddFeedbackParam(
1588 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1589 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1592 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001594 parameters.codecs.clear();
1595 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001596 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1598 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599}
1600
1601// Test that NACK is enabled on a new receive stream.
1602TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001603 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001604 cricket::AudioSendParameters parameters;
1605 parameters.codecs.push_back(kIsacCodec);
1606 parameters.codecs.push_back(kCn16000Codec);
1607 parameters.codecs[0].AddFeedbackParam(
1608 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1609 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001610 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001611 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612
solenberg2100c0b2017-03-01 11:29:29 -08001613 EXPECT_TRUE(AddRecvStream(kSsrcY));
1614 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1615 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1616 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617}
1618
stefanba4c0e42016-02-04 04:12:24 -08001619TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001620 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001621 cricket::AudioSendParameters send_parameters;
1622 send_parameters.codecs.push_back(kOpusCodec);
1623 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001624 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001625
1626 cricket::AudioRecvParameters recv_parameters;
1627 recv_parameters.codecs.push_back(kIsacCodec);
1628 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001629 EXPECT_TRUE(AddRecvStream(kSsrcX));
1630 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001631 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001632 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001633
ossudedfd282016-06-14 07:12:39 -07001634 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001637 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001638 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001639}
1640
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001641// Test that we can switch back and forth between Opus and ISAC with CN.
1642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001644
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001645 cricket::AudioSendParameters opus_parameters;
1646 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001647 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001648 {
ossu20a4b3f2017-04-27 02:08:52 -07001649 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1650 EXPECT_EQ(111, spec.payload_type);
1651 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001652 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001653
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters isac_parameters;
1655 isac_parameters.codecs.push_back(kIsacCodec);
1656 isac_parameters.codecs.push_back(kCn16000Codec);
1657 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001658 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001659 {
ossu20a4b3f2017-04-27 02:08:52 -07001660 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1661 EXPECT_EQ(103, spec.payload_type);
1662 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001663 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001664
solenberg059fb442016-10-26 05:12:24 -07001665 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001666 {
ossu20a4b3f2017-04-27 02:08:52 -07001667 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1668 EXPECT_EQ(111, spec.payload_type);
1669 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001670 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671}
1672
1673// Test that we handle various ways of specifying bitrate.
1674TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001675 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001676 cricket::AudioSendParameters parameters;
1677 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001678 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001679 {
ossu20a4b3f2017-04-27 02:08:52 -07001680 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1681 EXPECT_EQ(103, spec.payload_type);
1682 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1683 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001684 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001686 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001688 {
ossu20a4b3f2017-04-27 02:08:52 -07001689 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1690 EXPECT_EQ(103, spec.payload_type);
1691 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1692 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001693 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001695 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001696 {
ossu20a4b3f2017-04-27 02:08:52 -07001697 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1698 EXPECT_EQ(103, spec.payload_type);
1699 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1700 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001701 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001704 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001705 {
ossu20a4b3f2017-04-27 02:08:52 -07001706 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1707 EXPECT_EQ(0, spec.payload_type);
1708 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1709 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001710 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001712 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001714 {
ossu20a4b3f2017-04-27 02:08:52 -07001715 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1716 EXPECT_EQ(0, spec.payload_type);
1717 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1718 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001719 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001721 parameters.codecs[0] = kOpusCodec;
1722 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001723 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001724 {
ossu20a4b3f2017-04-27 02:08:52 -07001725 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1726 EXPECT_EQ(111, spec.payload_type);
1727 EXPECT_STREQ("opus", spec.format.name.c_str());
1728 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001729 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001730}
1731
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001732// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001733TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001734 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 cricket::AudioSendParameters parameters;
1736 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001737}
1738
1739// Test that we can set send codecs even with telephone-event codec as the first
1740// one on the list.
1741TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001742 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001743 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001744 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001745 parameters.codecs.push_back(kIsacCodec);
1746 parameters.codecs.push_back(kPcmuCodec);
1747 parameters.codecs[0].id = 98; // DTMF
1748 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001749 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001750 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1751 EXPECT_EQ(96, spec.payload_type);
1752 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001753 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001754}
1755
solenberg31642aa2016-03-14 08:00:37 -07001756// Test that payload type range is limited for telephone-event codec.
1757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001758 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001759 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001760 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001761 parameters.codecs.push_back(kIsacCodec);
1762 parameters.codecs[0].id = 0; // DTMF
1763 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001765 EXPECT_TRUE(channel_->CanInsertDtmf());
1766 parameters.codecs[0].id = 128; // DTMF
1767 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1768 EXPECT_FALSE(channel_->CanInsertDtmf());
1769 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001771 EXPECT_TRUE(channel_->CanInsertDtmf());
1772 parameters.codecs[0].id = -1; // DTMF
1773 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1774 EXPECT_FALSE(channel_->CanInsertDtmf());
1775}
1776
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001777// Test that we can set send codecs even with CN codec as the first
1778// one on the list.
1779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001780 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001781 cricket::AudioSendParameters parameters;
1782 parameters.codecs.push_back(kCn16000Codec);
1783 parameters.codecs.push_back(kIsacCodec);
1784 parameters.codecs.push_back(kPcmuCodec);
1785 parameters.codecs[0].id = 98; // wideband CN
1786 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001787 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001788 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1789 EXPECT_EQ(96, send_codec_spec.payload_type);
1790 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001791 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792}
1793
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001794// Test that we set VAD and DTMF types correctly as caller.
1795TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001796 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 cricket::AudioSendParameters parameters;
1798 parameters.codecs.push_back(kIsacCodec);
1799 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001801 parameters.codecs.push_back(kCn16000Codec);
1802 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001803 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001804 parameters.codecs[0].id = 96;
1805 parameters.codecs[2].id = 97; // wideband CN
1806 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001808 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1809 EXPECT_EQ(96, send_codec_spec.payload_type);
1810 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1811 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001812 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001813 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814}
1815
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001816// Test that we set VAD and DTMF types correctly as callee.
1817TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001818 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001819 cricket::AudioSendParameters parameters;
1820 parameters.codecs.push_back(kIsacCodec);
1821 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001822 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 parameters.codecs.push_back(kCn16000Codec);
1824 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001825 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs[0].id = 96;
1827 parameters.codecs[2].id = 97; // wideband CN
1828 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001829 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001830 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001831 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001832
ossu20a4b3f2017-04-27 02:08:52 -07001833 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1834 EXPECT_EQ(96, send_codec_spec.payload_type);
1835 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1836 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001837 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001838 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001839}
1840
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001841// Test that we only apply VAD if we have a CN codec that matches the
1842// send codec clockrate.
1843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001844 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001845 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001846 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 parameters.codecs.push_back(kIsacCodec);
1848 parameters.codecs.push_back(kCn16000Codec);
1849 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001850 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001851 {
ossu20a4b3f2017-04-27 02:08:52 -07001852 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1853 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1854 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001855 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001856 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001857 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001858 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001859 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001860 {
ossu20a4b3f2017-04-27 02:08:52 -07001861 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1862 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001863 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001864 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001865 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001866 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001867 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001868 {
ossu20a4b3f2017-04-27 02:08:52 -07001869 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1870 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1871 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001872 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001873 }
Brave Yao5225dd82015-03-26 07:39:19 +08001874 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001875 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001877 {
ossu20a4b3f2017-04-27 02:08:52 -07001878 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1879 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01001880 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001881 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882}
1883
1884// Test that we perform case-insensitive matching of codec names.
1885TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001886 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001887 cricket::AudioSendParameters parameters;
1888 parameters.codecs.push_back(kIsacCodec);
1889 parameters.codecs.push_back(kPcmuCodec);
1890 parameters.codecs.push_back(kCn16000Codec);
1891 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001892 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001893 parameters.codecs[0].name = "iSaC";
1894 parameters.codecs[0].id = 96;
1895 parameters.codecs[2].id = 97; // wideband CN
1896 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001897 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001898 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1899 EXPECT_EQ(96, send_codec_spec.payload_type);
1900 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1901 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001902 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001903 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001904}
1905
stefanba4c0e42016-02-04 04:12:24 -08001906class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1907 public:
1908 WebRtcVoiceEngineWithSendSideBweTest()
1909 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1910};
1911
1912TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1913 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001914 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001915 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001916 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1917 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1918 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001919 extension.id);
1920 return;
1921 }
1922 }
1923 FAIL() << "Transport sequence number extension not in header-extension list.";
1924}
1925
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001926// Test support for audio level header extension.
1927TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001928 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001929}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001930TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001931 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001932}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001933
solenbergd4adce42016-11-17 06:26:52 -08001934// Test support for transport sequence number header extension.
1935TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1936 TestSetSendRtpHeaderExtensions(
1937 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001938}
solenbergd4adce42016-11-17 06:26:52 -08001939TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1940 TestSetRecvRtpHeaderExtensions(
1941 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001942}
1943
solenberg1ac56142015-10-13 03:58:19 -07001944// Test that we can create a channel and start sending on it.
1945TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001946 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001947 SetSendParameters(send_parameters_);
1948 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001949 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001950 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001951 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001952}
1953
1954// Test that a channel will send if and only if it has a source and is enabled
1955// for sending.
1956TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001957 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001958 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001959 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001960 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001961 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1962 SetAudioSend(kSsrcX, true, &fake_source_);
1963 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1964 SetAudioSend(kSsrcX, true, nullptr);
1965 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001966}
1967
solenberg94218532016-06-16 10:53:22 -07001968// Test that a channel is muted/unmuted.
1969TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1970 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001972 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1973 SetAudioSend(kSsrcX, true, nullptr);
1974 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1975 SetAudioSend(kSsrcX, false, nullptr);
1976 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001977}
1978
solenberg6d6e7c52016-04-13 09:07:30 -07001979// Test that SetSendParameters() does not alter a stream's send state.
1980TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1981 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001982 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001983
1984 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001985 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001986 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001987
1988 // Changing RTP header extensions will recreate the AudioSendStream.
1989 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001990 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001992 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001993
1994 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001995 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001996 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001997
1998 // Changing RTP header extensions will recreate the AudioSendStream.
1999 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002001 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002002}
2003
solenberg1ac56142015-10-13 03:58:19 -07002004// Test that we can create a channel and start playing out on it.
2005TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002006 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002007 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002008 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002009 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002010 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002011 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012}
2013
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002014// Test that we can add and remove send streams.
2015TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2016 SetupForMultiSendStream();
2017
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002018 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002019 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002020
solenbergc96df772015-10-21 13:01:53 -07002021 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002022 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002023 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002024 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002025 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002026 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027 }
tfarina5237aaf2015-11-10 23:44:30 -08002028 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029
solenbergc96df772015-10-21 13:01:53 -07002030 // Delete the send streams.
2031 for (uint32_t ssrc : kSsrcs4) {
2032 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002033 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002034 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035 }
solenbergc96df772015-10-21 13:01:53 -07002036 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037}
2038
2039// Test SetSendCodecs correctly configure the codecs in all send streams.
2040TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2041 SetupForMultiSendStream();
2042
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002044 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002046 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002047 }
2048
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002049 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002050 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002051 parameters.codecs.push_back(kIsacCodec);
2052 parameters.codecs.push_back(kCn16000Codec);
2053 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002055
2056 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002057 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002058 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2059 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002060 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2061 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2062 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002063 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002064 }
2065
minyue7a973442016-10-20 03:27:12 -07002066 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002067 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002068 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002069 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002070 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2071 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002072 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2073 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
Oskar Sundbom78807582017-11-16 11:09:55 +01002074 EXPECT_EQ(rtc::nullopt, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075 }
2076}
2077
2078// Test we can SetSend on all send streams correctly.
2079TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2080 SetupForMultiSendStream();
2081
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002082 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002083 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002084 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002085 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002086 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002087 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088 }
2089
2090 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002091 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002092 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002093 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002094 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002095 }
2096
2097 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002098 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002099 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002100 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002101 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002102 }
2103}
2104
2105// Test we can set the correct statistics on all send streams.
2106TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2107 SetupForMultiSendStream();
2108
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002109 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002110 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002111 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002112 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002113 }
solenberg85a04962015-10-27 03:35:21 -07002114
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002115 // Create a receive stream to check that none of the send streams end up in
2116 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002117 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002118
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002119 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002120 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002121 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002122 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002123
solenberg85a04962015-10-27 03:35:21 -07002124 // Check stats for the added streams.
2125 {
2126 cricket::VoiceMediaInfo info;
2127 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002128
solenberg85a04962015-10-27 03:35:21 -07002129 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002130 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002131 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002132 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002133 }
hbos1acfbd22016-11-17 23:43:29 -08002134 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002135
2136 // We have added one receive stream. We should see empty stats.
2137 EXPECT_EQ(info.receivers.size(), 1u);
2138 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002139 }
solenberg1ac56142015-10-13 03:58:19 -07002140
solenberg2100c0b2017-03-01 11:29:29 -08002141 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002142 {
2143 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002145 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002146 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002147 EXPECT_EQ(0u, info.receivers.size());
2148 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002149
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002150 // Deliver a new packet - a default receive stream should be created and we
2151 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002152 {
2153 cricket::VoiceMediaInfo info;
2154 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2155 SetAudioReceiveStreamStats();
2156 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002157 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002158 EXPECT_EQ(1u, info.receivers.size());
2159 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002160 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002161 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002162}
2163
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002164// Test that we can add and remove receive streams, and do proper send/playout.
2165// We can receive on multiple streams while sending one stream.
2166TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002167 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168
solenberg1ac56142015-10-13 03:58:19 -07002169 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002170 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002171 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002172
solenberg1ac56142015-10-13 03:58:19 -07002173 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002174 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002175 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002176 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177
solenberg1ac56142015-10-13 03:58:19 -07002178 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002179 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180
2181 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002182 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2183 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2184 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185
2186 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002187 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002188 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002189
2190 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002191 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002192 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2193 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194
aleloi84ef6152016-08-04 05:28:21 -07002195 // Restart playout and make sure recv streams are played out.
2196 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002197 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2198 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002199
aleloi84ef6152016-08-04 05:28:21 -07002200 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002201 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2202 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002203}
2204
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002205// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002206// and start sending on it.
2207TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002208 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002209 send_parameters_.options.adjust_agc_delta = -10;
solenberg76377c52017-02-21 00:54:31 -08002210 EXPECT_CALL(apm_gc_,
2211 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002212 SetSendParameters(send_parameters_);
2213 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002214 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002215 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002217}
2218
wu@webrtc.org97077a32013-10-25 21:18:33 +00002219TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002220 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002221 EXPECT_CALL(adm_,
2222 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002223 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2224 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002225 send_parameters_.options.tx_agc_target_dbov = 3;
2226 send_parameters_.options.tx_agc_digital_compression_gain = 9;
2227 send_parameters_.options.tx_agc_limiter = true;
2228 send_parameters_.options.auto_gain_control = 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.
Oskar Sundbom78807582017-11-16 11:09:55 +01002236 send_parameters_.options.adjust_agc_delta = -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());
Oskar Sundbom78807582017-11-16 11:09:55 +01002243 send_parameters_.options.audio_network_adaptor = true;
2244 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002245 SetSendParameters(send_parameters_);
2246 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002247 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002248}
2249
2250TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2251 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002252 send_parameters_.options.audio_network_adaptor = true;
2253 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002254 SetSendParameters(send_parameters_);
2255 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002256 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002257 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002258 options.audio_network_adaptor = false;
solenberg2100c0b2017-03-01 11:29:29 -08002259 SetAudioSend(kSsrcX, true, nullptr, &options);
Oskar Sundbom78807582017-11-16 11:09:55 +01002260 EXPECT_EQ(rtc::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002261}
2262
2263TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2264 EXPECT_TRUE(SetupSendStream());
Oskar Sundbom78807582017-11-16 11:09:55 +01002265 send_parameters_.options.audio_network_adaptor = true;
2266 send_parameters_.options.audio_network_adaptor_config = {"1234"};
minyue6b825df2016-10-31 04:08:32 -07002267 SetSendParameters(send_parameters_);
2268 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002269 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002270 const int initial_num = call_.GetNumCreatedSendStreams();
2271 cricket::AudioOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002272 options.audio_network_adaptor = rtc::nullopt;
minyue6b825df2016-10-31 04:08:32 -07002273 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2274 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002275 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002276 // AudioSendStream not expected to be recreated.
2277 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2278 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002279 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002280}
2281
michaelt6672b262017-01-11 10:17:59 -08002282class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2283 : public WebRtcVoiceEngineTestFake {
2284 public:
2285 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2286 : WebRtcVoiceEngineTestFake(
2287 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2288 "Enabled/") {}
2289};
2290
2291TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2292 EXPECT_TRUE(SetupSendStream());
2293 cricket::AudioSendParameters parameters;
2294 parameters.codecs.push_back(kOpusCodec);
2295 SetSendParameters(parameters);
2296 const int initial_num = call_.GetNumCreatedSendStreams();
2297 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2298
2299 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2300 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002301 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2302 constexpr int kMinOverheadBps =
2303 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002304
2305 constexpr int kOpusMinBitrateBps = 6000;
2306 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002307 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002308 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002309 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002310 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002311
Oskar Sundbom78807582017-11-16 11:09:55 +01002312 parameters.options.audio_network_adaptor = true;
2313 parameters.options.audio_network_adaptor_config = {"1234"};
michaelt6672b262017-01-11 10:17:59 -08002314 SetSendParameters(parameters);
2315
ossu11bfc532017-02-16 05:37:06 -08002316 constexpr int kMinOverheadWithAnaBps =
2317 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002318
2319 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002320 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002321
minyuececec102017-03-27 13:04:25 -07002322 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002323 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002324}
2325
minyuececec102017-03-27 13:04:25 -07002326// This test is similar to
2327// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2328// additional field trial.
2329TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2330 SetRtpSendParameterUpdatesMaxBitrate) {
2331 EXPECT_TRUE(SetupSendStream());
2332 cricket::AudioSendParameters send_parameters;
2333 send_parameters.codecs.push_back(kOpusCodec);
2334 SetSendParameters(send_parameters);
2335
2336 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2337 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2338 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2339
2340 constexpr int kMaxBitrateBps = 6000;
Oskar Sundbom78807582017-11-16 11:09:55 +01002341 rtp_parameters.encodings[0].max_bitrate_bps = kMaxBitrateBps;
minyuececec102017-03-27 13:04:25 -07002342 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2343
2344 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2345#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2346 constexpr int kMinOverhead = 3333;
2347#else
2348 constexpr int kMinOverhead = 6666;
2349#endif
2350 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2351}
2352
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002353// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002354// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002355TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002356 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002357 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002358}
2359
2360TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2361 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002362 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002363 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002364 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002365 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002366 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002367 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002368 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369
solenberg85a04962015-10-27 03:35:21 -07002370 // Check stats for the added streams.
2371 {
2372 cricket::VoiceMediaInfo info;
2373 EXPECT_EQ(true, channel_->GetStats(&info));
2374
2375 // We have added one send stream. We should see the stats we've set.
2376 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002377 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002378 // We have added one receive stream. We should see empty stats.
2379 EXPECT_EQ(info.receivers.size(), 1u);
2380 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2381 }
solenberg1ac56142015-10-13 03:58:19 -07002382
solenberg566ef242015-11-06 15:34:49 -08002383 // Start sending - this affects some reported stats.
2384 {
2385 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002386 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002387 EXPECT_EQ(true, channel_->GetStats(&info));
2388 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002389 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002390 }
2391
solenberg2100c0b2017-03-01 11:29:29 -08002392 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002393 {
2394 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002395 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002396 EXPECT_EQ(true, channel_->GetStats(&info));
2397 EXPECT_EQ(1u, info.senders.size());
2398 EXPECT_EQ(0u, info.receivers.size());
2399 }
solenberg1ac56142015-10-13 03:58:19 -07002400
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002401 // Deliver a new packet - a default receive stream should be created and we
2402 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002403 {
2404 cricket::VoiceMediaInfo info;
2405 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2406 SetAudioReceiveStreamStats();
2407 EXPECT_EQ(true, channel_->GetStats(&info));
2408 EXPECT_EQ(1u, info.senders.size());
2409 EXPECT_EQ(1u, info.receivers.size());
2410 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002411 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002412 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413}
2414
2415// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002416// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002418 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002419 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2420 EXPECT_TRUE(AddRecvStream(kSsrcY));
2421 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422}
2423
2424// Test that the local SSRC is the same on sending and receiving channels if the
2425// receive channel is created before the send channel.
2426TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002427 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002428 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002429 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002430 cricket::StreamParams::CreateLegacy(kSsrcX)));
2431 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2432 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433}
2434
2435// Test that we can properly receive packets.
2436TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002437 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002438 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002440
2441 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2442 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443}
2444
2445// Test that we can properly receive packets on multiple streams.
2446TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002448 const uint32_t ssrc1 = 1;
2449 const uint32_t ssrc2 = 2;
2450 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002451 EXPECT_TRUE(AddRecvStream(ssrc1));
2452 EXPECT_TRUE(AddRecvStream(ssrc2));
2453 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002455 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002456 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002458 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459 }
mflodman3d7db262016-04-29 00:57:13 -07002460
2461 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2462 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2463 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2464
2465 EXPECT_EQ(s1.received_packets(), 0);
2466 EXPECT_EQ(s2.received_packets(), 0);
2467 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002468
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002470 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[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002475 EXPECT_EQ(s1.received_packets(), 1);
2476 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2477 EXPECT_EQ(s2.received_packets(), 0);
2478 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002479
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002480 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002481 EXPECT_EQ(s1.received_packets(), 1);
2482 EXPECT_EQ(s2.received_packets(), 1);
2483 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2484 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002485
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002486 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_EQ(s1.received_packets(), 1);
2488 EXPECT_EQ(s2.received_packets(), 1);
2489 EXPECT_EQ(s3.received_packets(), 1);
2490 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002491
mflodman3d7db262016-04-29 00:57:13 -07002492 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2493 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2494 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495}
2496
solenberg2100c0b2017-03-01 11:29:29 -08002497// Test that receiving on an unsignaled stream works (a stream is created).
2498TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002499 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002500 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2501
solenberg7e63ef02015-11-20 00:19:43 -08002502 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002503
2504 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002505 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2506 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002507}
2508
solenberg2100c0b2017-03-01 11:29:29 -08002509// Test that receiving N unsignaled stream works (streams will be created), and
2510// that packets are forwarded to them all.
2511TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002512 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002513 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002514 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2515
solenberg2100c0b2017-03-01 11:29:29 -08002516 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002517 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002518 rtc::SetBE32(&packet[8], ssrc);
2519 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002520
solenberg2100c0b2017-03-01 11:29:29 -08002521 // Verify we have one new stream for each loop iteration.
2522 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002523 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2524 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002525 }
mflodman3d7db262016-04-29 00:57:13 -07002526
solenberg2100c0b2017-03-01 11:29:29 -08002527 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002528 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002529 rtc::SetBE32(&packet[8], ssrc);
2530 DeliverPacket(packet, sizeof(packet));
2531
solenbergebb349d2017-03-13 05:46:15 -07002532 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002533 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2534 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2535 }
2536
2537 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2538 constexpr uint32_t kAnotherSsrc = 667;
2539 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002540 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002541
2542 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002543 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002544 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002545 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002546 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2547 EXPECT_EQ(2, streams[i]->received_packets());
2548 }
2549 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2550 EXPECT_EQ(1, streams[i]->received_packets());
2551 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002552 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002553}
2554
solenberg2100c0b2017-03-01 11:29:29 -08002555// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002556// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002557TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002558 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002559 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002560 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2561
2562 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002563 const uint32_t signaled_ssrc = 1;
2564 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002565 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002566 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002567 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2568 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002569 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002570
2571 // Note that the first unknown SSRC cannot be 0, because we only support
2572 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002573 const uint32_t unsignaled_ssrc = 7011;
2574 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002575 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002576 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2577 packet, sizeof(packet)));
2578 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2579
2580 DeliverPacket(packet, sizeof(packet));
2581 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2582
2583 rtc::SetBE32(&packet[8], signaled_ssrc);
2584 DeliverPacket(packet, sizeof(packet));
2585 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2586 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002587}
2588
solenberg4904fb62017-02-17 12:01:14 -08002589// Two tests to verify that adding a receive stream with the same SSRC as a
2590// previously added unsignaled stream will only recreate underlying stream
2591// objects if the stream parameters have changed.
2592TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2593 EXPECT_TRUE(SetupChannel());
2594
2595 // Spawn unsignaled stream with SSRC=1.
2596 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2597 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2598 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2599 sizeof(kPcmuFrame)));
2600
2601 // Verify that the underlying stream object in Call is not recreated when a
2602 // stream with SSRC=1 is added.
2603 const auto& streams = call_.GetAudioReceiveStreams();
2604 EXPECT_EQ(1, streams.size());
2605 int audio_receive_stream_id = streams.front()->id();
2606 EXPECT_TRUE(AddRecvStream(1));
2607 EXPECT_EQ(1, streams.size());
2608 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2609}
2610
2611TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2612 EXPECT_TRUE(SetupChannel());
2613
2614 // Spawn unsignaled stream with SSRC=1.
2615 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2616 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2617 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2618 sizeof(kPcmuFrame)));
2619
2620 // Verify that the underlying stream object in Call *is* recreated when a
2621 // stream with SSRC=1 is added, and which has changed stream parameters.
2622 const auto& streams = call_.GetAudioReceiveStreams();
2623 EXPECT_EQ(1, streams.size());
2624 int audio_receive_stream_id = streams.front()->id();
2625 cricket::StreamParams stream_params;
2626 stream_params.ssrcs.push_back(1);
2627 stream_params.sync_label = "sync_label";
2628 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2629 EXPECT_EQ(1, streams.size());
2630 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2631}
2632
solenberg0a617e22015-10-20 15:49:38 -07002633// Test that we properly handle failures to add a receive stream.
2634TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002635 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002636 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002637 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002638}
2639
solenberg0a617e22015-10-20 15:49:38 -07002640// Test that we properly handle failures to add a send stream.
2641TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002642 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002643 voe_.set_fail_create_channel(true);
2644 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2645}
2646
solenberg1ac56142015-10-13 03:58:19 -07002647// Test that AddRecvStream creates new stream.
2648TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002649 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002650 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002651 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002652 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653}
2654
2655// Test that after adding a recv stream, we do not decode more codecs than
2656// those previously passed into SetRecvCodecs.
2657TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002658 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002659 cricket::AudioRecvParameters parameters;
2660 parameters.codecs.push_back(kIsacCodec);
2661 parameters.codecs.push_back(kPcmuCodec);
2662 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002663 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002664 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2665 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2666 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667}
2668
2669// Test that we properly clean up any streams that were added, even if
2670// not explicitly removed.
2671TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002672 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002673 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002674 EXPECT_TRUE(AddRecvStream(1));
2675 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002676 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2677 delete channel_;
2678 channel_ = NULL;
2679 EXPECT_EQ(0, voe_.GetNumChannels());
2680}
2681
wu@webrtc.org78187522013-10-07 23:32:02 +00002682TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002683 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002684 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002685}
2686
2687TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002688 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002689 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002690 // Manually delete channel to simulate a failure.
2691 int channel = voe_.GetLastChannel();
2692 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2693 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002694 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002695 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002696 EXPECT_NE(channel, new_channel);
2697 // The last created channel is deleted too.
2698 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002699}
2700
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002701// Test the InsertDtmf on default send stream as caller.
2702TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002703 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704}
2705
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002706// Test the InsertDtmf on default send stream as callee
2707TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002708 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002709}
2710
2711// Test the InsertDtmf on specified send stream as caller.
2712TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002713 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002714}
2715
2716// Test the InsertDtmf on specified send stream as callee.
2717TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002718 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719}
2720
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002722 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002723 EXPECT_CALL(adm_,
2724 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2725 EXPECT_CALL(adm_,
2726 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2727 EXPECT_CALL(adm_,
2728 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002729
solenberg246b8172015-12-08 09:50:23 -08002730 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2731 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732
solenberg246b8172015-12-08 09:50:23 -08002733 // Nothing set in AudioOptions, so everything should be as default.
2734 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002735 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002736 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002737 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2738 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002739
2740 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002741 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2742 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002743 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002744 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002745
2746 // Turn echo cancellation back on, with settings, and make sure
2747 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002748 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2749 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002750 send_parameters_.options.echo_cancellation = true;
solenberg059fb442016-10-26 05:12:24 -07002751 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002752
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002753 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2754 // control.
solenberg76377c52017-02-21 00:54:31 -08002755 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002757 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002758 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002759
2760 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002761 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002763 send_parameters_.options.delay_agnostic_aec = false;
2764 send_parameters_.options.extended_filter_aec = false;
2765 send_parameters_.options.echo_cancellation = false;
solenberg059fb442016-10-26 05:12:24 -07002766 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002767
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002768 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002771 send_parameters_.options.delay_agnostic_aec = true;
solenberg059fb442016-10-26 05:12:24 -07002772 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002773
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002775 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2776 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2777 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2778 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002779 send_parameters_.options.auto_gain_control = false;
solenberg059fb442016-10-26 05:12:24 -07002780 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781
2782 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002783 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2784 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2785 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
Oskar Sundbom78807582017-11-16 11:09:55 +01002787 send_parameters_.options.auto_gain_control = true;
2788 send_parameters_.options.adjust_agc_delta = rtc::nullopt;
solenberg059fb442016-10-26 05:12:24 -07002789 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002790
2791 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002792 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2793 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2794 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2795 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2796 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2797 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2798 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
Oskar Sundbom78807582017-11-16 11:09:55 +01002799 send_parameters_.options.noise_suppression = false;
2800 send_parameters_.options.highpass_filter = false;
2801 send_parameters_.options.typing_detection = false;
2802 send_parameters_.options.stereo_swapping = true;
solenberg059fb442016-10-26 05:12:24 -07002803 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002804 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002805
solenberg1ac56142015-10-13 03:58:19 -07002806 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002807 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2808 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2809 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2813 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002814 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002815}
2816
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002818 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002819 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002820 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002821 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002822 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002823 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002824 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002825 EXPECT_CALL(adm_,
2826 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2827 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2828 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002829 webrtc::AudioProcessing::Config apm_config;
2830 EXPECT_CALL(*apm_, GetConfig())
2831 .Times(10)
2832 .WillRepeatedly(ReturnPointee(&apm_config));
2833 EXPECT_CALL(*apm_, ApplyConfig(_))
2834 .Times(10)
2835 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002836 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002837
kwiberg686a8ef2016-02-26 03:00:35 -08002838 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002839 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002840 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002841 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002842 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002843 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002844
2845 // Have to add a stream to make SetSend work.
2846 cricket::StreamParams stream1;
2847 stream1.ssrcs.push_back(1);
2848 channel1->AddSendStream(stream1);
2849 cricket::StreamParams stream2;
2850 stream2.ssrcs.push_back(2);
2851 channel2->AddSendStream(stream2);
2852
2853 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002854 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002855 parameters_options_all.options.echo_cancellation = true;
2856 parameters_options_all.options.auto_gain_control = true;
2857 parameters_options_all.options.noise_suppression = true;
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2859 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2860 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2861 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2862 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002863 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002864 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002865 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002866 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002867
2868 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002869 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002870 parameters_options_no_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002871 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2872 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2873 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2874 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2875 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002876 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002877 cricket::AudioOptions expected_options = parameters_options_all.options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002878 expected_options.echo_cancellation = true;
2879 expected_options.auto_gain_control = true;
2880 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002881 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
2883 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002884 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002885 parameters_options_no_agc.options.auto_gain_control = false;
solenberg76377c52017-02-21 00:54:31 -08002886 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2888 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2889 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002891 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Oskar Sundbom78807582017-11-16 11:09:55 +01002892 expected_options.echo_cancellation = true;
2893 expected_options.auto_gain_control = false;
2894 expected_options.noise_suppression = true;
solenberg66f43392015-09-09 01:36:22 -07002895 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2898 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2899 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
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(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002909 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910
solenberg76377c52017-02-21 00:54:31 -08002911 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2912 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2913 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2914 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2915 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002916 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002919 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2920 send_parameters_;
Oskar Sundbom78807582017-11-16 11:09:55 +01002921 parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
2922 parameters_options_no_agc_nor_ns.options.noise_suppression = false;
solenberg76377c52017-02-21 00:54:31 -08002923 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2924 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2925 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2926 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2927 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002928 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Oskar Sundbom78807582017-11-16 11:09:55 +01002929 expected_options.echo_cancellation = true;
2930 expected_options.auto_gain_control = false;
2931 expected_options.noise_suppression = false;
solenberg66f43392015-09-09 01:36:22 -07002932 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933}
2934
wu@webrtc.orgde305012013-10-31 15:40:38 +00002935// This test verifies DSCP settings are properly applied on voice media channel.
2936TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002937 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002938 cricket::FakeNetworkInterface network_interface;
2939 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002940 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002941
peahb1c9d1d2017-07-25 15:45:24 -07002942 webrtc::AudioProcessing::Config apm_config;
2943 EXPECT_CALL(*apm_, GetConfig())
2944 .Times(3)
2945 .WillRepeatedly(ReturnPointee(&apm_config));
2946 EXPECT_CALL(*apm_, ApplyConfig(_))
2947 .Times(3)
2948 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002949 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002950
solenbergbc37fc82016-04-04 09:54:44 -07002951 channel.reset(
2952 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002953 channel->SetInterface(&network_interface);
2954 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2955 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2956
2957 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002958 channel.reset(
2959 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002960 channel->SetInterface(&network_interface);
2961 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2962
2963 // Verify that setting the option to false resets the
2964 // DiffServCodePoint.
2965 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002966 channel.reset(
2967 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002968 channel->SetInterface(&network_interface);
2969 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2970 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2971
2972 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002973}
2974
solenberg1ac56142015-10-13 03:58:19 -07002975TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002976 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977 cricket::WebRtcVoiceMediaChannel* media_channel =
2978 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002979 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002980 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002981 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002982 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2983 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2984 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002985 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002986 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987}
2988
solenberg1ac56142015-10-13 03:58:19 -07002989TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002990 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002991 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002992 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2993 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2994 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002995 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002996 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002997 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2998 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002999 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003000 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003001 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003002 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003003}
3004
solenberg4bac9c52015-10-09 02:32:53 -07003005TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003006 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003007 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003009 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003011 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3012 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3013 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003014}
3015
solenberg2100c0b2017-03-01 11:29:29 -08003016TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003017 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003018
3019 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003020 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003021 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3022
3023 // Should remember the volume "2" which will be set on new unsignaled streams,
3024 // and also set the gain to 2 on existing unsignaled streams.
3025 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3026 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3027
3028 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3029 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3030 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3031 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3032 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3033 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3034
3035 // Setting gain with SSRC=0 should affect all unsignaled streams.
3036 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003037 if (kMaxUnsignaledRecvStreams > 1) {
3038 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3039 }
solenberg2100c0b2017-03-01 11:29:29 -08003040 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3041
3042 // Setting gain on an individual stream affects only that.
3043 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003044 if (kMaxUnsignaledRecvStreams > 1) {
3045 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3046 }
solenberg2100c0b2017-03-01 11:29:29 -08003047 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048}
3049
pbos8fc7fa72015-07-15 08:02:58 -07003050TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003051 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003052 const std::string kSyncLabel = "AvSyncLabel";
3053
solenbergff976312016-03-30 23:28:51 -07003054 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003055 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3056 sp.sync_label = kSyncLabel;
3057 // Creating two channels to make sure that sync label is set properly for both
3058 // the default voice channel and following ones.
3059 EXPECT_TRUE(channel_->AddRecvStream(sp));
3060 sp.ssrcs[0] += 1;
3061 EXPECT_TRUE(channel_->AddRecvStream(sp));
3062
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003063 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003064 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003065 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003066 << "SyncGroup should be set based on sync_label";
3067 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003068 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003069 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003070}
3071
solenberg3a941542015-11-16 07:34:50 -08003072// TODO(solenberg): Remove, once recv streams are configured through Call.
3073// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003074TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003075 // Test that setting the header extensions results in the expected state
3076 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003077 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003078 ssrcs.push_back(223);
3079 ssrcs.push_back(224);
3080
solenbergff976312016-03-30 23:28:51 -07003081 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003082 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003083 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003084 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003085 cricket::StreamParams::CreateLegacy(ssrc)));
3086 }
3087
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003088 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003089 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003090 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 EXPECT_NE(nullptr, s);
3092 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3093 }
3094
3095 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003096 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003097 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003098 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003099 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003100 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003101 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003102 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003103 EXPECT_NE(nullptr, s);
3104 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003105 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3106 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003107 for (const auto& s_ext : s_exts) {
3108 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003109 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003110 }
3111 }
3112 }
3113 }
3114
3115 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003116 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003117 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003118 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119 EXPECT_NE(nullptr, s);
3120 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3121 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003122}
3123
3124TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3125 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003126 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003127 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 static const unsigned char kRtcp[] = {
3129 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3130 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3133 };
jbaucheec21bd2016-03-20 06:15:43 -07003134 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003135
solenbergff976312016-03-30 23:28:51 -07003136 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003137 cricket::WebRtcVoiceMediaChannel* media_channel =
3138 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003139 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003140 EXPECT_TRUE(media_channel->AddRecvStream(
3141 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3142
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003143 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003144 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003145 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003146 EXPECT_EQ(0, s->received_packets());
3147 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3148 EXPECT_EQ(1, s->received_packets());
3149 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3150 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003151}
Minyue2013aec2015-05-13 14:14:42 +02003152
solenberg0a617e22015-10-20 15:49:38 -07003153// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003154// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003155TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003156 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003157 EXPECT_TRUE(AddRecvStream(kSsrcY));
3158 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003159 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003160 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3161 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3162 EXPECT_TRUE(AddRecvStream(kSsrcW));
3163 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003164}
3165
solenberg7602aab2016-11-14 11:30:07 -08003166TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3167 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003168 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003169 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003170 cricket::StreamParams::CreateLegacy(kSsrcY)));
3171 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3172 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3173 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003174 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003175 cricket::StreamParams::CreateLegacy(kSsrcW)));
3176 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3177 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003178}
stefan658910c2015-09-03 05:48:32 -07003179
deadbeef884f5852016-01-15 09:20:04 -08003180TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003181 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003182 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3183 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003184
3185 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003186 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3187 EXPECT_TRUE(AddRecvStream(kSsrcX));
3188 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003189
3190 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003191 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3192 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003193
3194 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003195 channel_->SetRawAudioSink(kSsrcX, nullptr);
3196 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003197}
3198
solenberg2100c0b2017-03-01 11:29:29 -08003199TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003200 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003201 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3202 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003203 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3204 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // Should be able to set a default sink even when no stream exists.
3207 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3208
solenberg2100c0b2017-03-01 11:29:29 -08003209 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3210 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003211 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003212 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003213
3214 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003215 channel_->SetRawAudioSink(kSsrc0, nullptr);
3216 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003217
3218 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003219 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3220 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003221
3222 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003223 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003224 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003225 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3226
3227 // Spawn another unsignaled stream - it should be assigned the default sink
3228 // and the previous unsignaled stream should lose it.
3229 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3230 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3231 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3232 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003233 if (kMaxUnsignaledRecvStreams > 1) {
3234 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3235 }
solenberg2100c0b2017-03-01 11:29:29 -08003236 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3237
3238 // Reset the default sink - the second unsignaled stream should lose it.
3239 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003240 if (kMaxUnsignaledRecvStreams > 1) {
3241 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3242 }
solenberg2100c0b2017-03-01 11:29:29 -08003243 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3244
3245 // Try setting the default sink while two streams exists.
3246 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003247 if (kMaxUnsignaledRecvStreams > 1) {
3248 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3249 }
solenberg2100c0b2017-03-01 11:29:29 -08003250 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3251
3252 // Try setting the sink for the first unsignaled stream using its known SSRC.
3253 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003254 if (kMaxUnsignaledRecvStreams > 1) {
3255 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3256 }
solenberg2100c0b2017-03-01 11:29:29 -08003257 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003258 if (kMaxUnsignaledRecvStreams > 1) {
3259 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3260 }
deadbeef884f5852016-01-15 09:20:04 -08003261}
3262
skvlad7a43d252016-03-22 15:32:27 -07003263// Test that, just like the video channel, the voice channel communicates the
3264// network state to the call.
3265TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003266 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003267
3268 EXPECT_EQ(webrtc::kNetworkUp,
3269 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3270 EXPECT_EQ(webrtc::kNetworkUp,
3271 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3272
3273 channel_->OnReadyToSend(false);
3274 EXPECT_EQ(webrtc::kNetworkDown,
3275 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3276 EXPECT_EQ(webrtc::kNetworkUp,
3277 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3278
3279 channel_->OnReadyToSend(true);
3280 EXPECT_EQ(webrtc::kNetworkUp,
3281 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3282 EXPECT_EQ(webrtc::kNetworkUp,
3283 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3284}
3285
aleloi18e0b672016-10-04 02:45:47 -07003286// Test that playout is still started after changing parameters
3287TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3288 SetupRecvStream();
3289 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003290 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003291
3292 // Changing RTP header extensions will recreate the AudioReceiveStream.
3293 cricket::AudioRecvParameters parameters;
3294 parameters.extensions.push_back(
3295 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3296 channel_->SetRecvParameters(parameters);
3297
solenberg2100c0b2017-03-01 11:29:29 -08003298 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003299}
3300
stefan658910c2015-09-03 05:48:32 -07003301// Tests that the library initializes and shuts down properly.
3302TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003303 // If the VoiceEngine wants to gather available codecs early, that's fine but
3304 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003305 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003306 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3307 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003308 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003309 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003310 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003311 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003312 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003313 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003314 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003315 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3316 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003317 EXPECT_TRUE(channel != nullptr);
3318 delete channel;
solenbergff976312016-03-30 23:28:51 -07003319}
stefan658910c2015-09-03 05:48:32 -07003320
solenbergff976312016-03-30 23:28:51 -07003321// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003322TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3323 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003324 EXPECT_CALL(adm, AddRef()).Times(3);
3325 EXPECT_CALL(adm, Release())
3326 .Times(3)
3327 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003328 {
peaha9cc40b2017-06-29 08:32:09 -07003329 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3330 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003331 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003332 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003333 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003334 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003335 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003336 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003337 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003338 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3339 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3340 EXPECT_TRUE(channel != nullptr);
3341 delete channel;
3342 }
stefan658910c2015-09-03 05:48:32 -07003343}
3344
ossu20a4b3f2017-04-27 02:08:52 -07003345// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3346TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003347 // TODO(ossu): Why are the payload types of codecs with non-static payload
3348 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003349 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003350 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3351 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003352 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003353 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003354 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003355 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003356 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003357 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3358 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3359 (clockrate == 0 || codec.clockrate == clockrate);
3360 };
3361 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003362 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003363 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003364 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003365 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003366 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003367 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003368 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003369 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003370 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003371 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003372 EXPECT_EQ(126, codec.id);
3373 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3374 // Remove these checks once both send and receive side assigns payload types
3375 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003376 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003377 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003378 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003379 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003380 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003381 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003382 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(111, codec.id);
3384 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3385 EXPECT_EQ("10", codec.params.find("minptime")->second);
3386 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3387 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003388 }
3389 }
stefan658910c2015-09-03 05:48:32 -07003390}
3391
3392// Tests that VoE supports at least 32 channels
3393TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003394 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003395 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3396 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003397 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003398 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003399 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003400 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003401 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003402 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003403 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003404
3405 cricket::VoiceMediaChannel* channels[32];
3406 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003407 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003408 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3409 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003410 if (!channel)
3411 break;
stefan658910c2015-09-03 05:48:32 -07003412 channels[num_channels++] = channel;
3413 }
3414
tfarina5237aaf2015-11-10 23:44:30 -08003415 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003416 EXPECT_EQ(expected, num_channels);
3417
3418 while (num_channels > 0) {
3419 delete channels[--num_channels];
3420 }
stefan658910c2015-09-03 05:48:32 -07003421}
3422
3423// Test that we set our preferred codecs properly.
3424TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003425 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3426 // - Check that our builtin codecs are usable by Channel.
3427 // - The codecs provided by the engine is usable by Channel.
3428 // It does not check that the codecs in the RecvParameters are actually
3429 // what we sent in - though it's probably reasonable to expect so, if
3430 // SetRecvParameters returns true.
3431 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003432 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003433 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3434 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003435 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003436 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003437 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003438 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003439 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003440 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003441 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003442 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3443 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003444 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003445 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003446 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003447}
ossu9def8002017-02-09 05:14:32 -08003448
3449TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3450 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003451 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3452 {48000, 2, 16000, 10000, 20000}};
3453 spec1.info.allow_comfort_noise = false;
3454 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003455 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003456 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3457 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003458 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003459 specs.push_back(webrtc::AudioCodecSpec{
3460 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3461 {16000, 1, 13300}});
3462 specs.push_back(
3463 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3464 specs.push_back(
3465 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003466
ossueb1fde42017-05-02 06:46:30 -07003467 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3468 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3469 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003470 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003471 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003472 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003473 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003474
peaha9cc40b2017-06-29 08:32:09 -07003475 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3476 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003477 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003478 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003479 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003480 auto codecs = engine.recv_codecs();
3481 EXPECT_EQ(11, codecs.size());
3482
3483 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3484 // check the actual values safely, to provide better test results.
3485 auto get_codec =
3486 [&codecs](size_t index) -> const cricket::AudioCodec& {
3487 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3488 if (codecs.size() > index)
3489 return codecs[index];
3490 return missing_codec;
3491 };
3492
3493 // Ensure the general codecs are generated first and in order.
3494 for (size_t i = 0; i != specs.size(); ++i) {
3495 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3496 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3497 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3498 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3499 }
3500
3501 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003502 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003503 auto find_codec =
3504 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3505 for (size_t i = 0; i != codecs.size(); ++i) {
3506 const cricket::AudioCodec& codec = codecs[i];
3507 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3508 codec.clockrate == format.clockrate_hz &&
3509 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003510 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003511 }
3512 }
3513 return -1;
3514 };
3515
3516 // Ensure all supplementary codecs are generated last. Their internal ordering
3517 // is not important.
3518 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3519 const int num_specs = static_cast<int>(specs.size());
3520 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3521 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3522 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3523 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3524 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3525 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3526 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3527}