blob: e8c9a221a14ed602ead6c0e404c2a2cbc5782f98 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070012#include <utility>
kwiberg686a8ef2016-02-26 03:00:35 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
16#include "call/call.h"
17#include "logging/rtc_event_log/rtc_event_log.h"
18#include "media/base/fakemediaengine.h"
19#include "media/base/fakenetworkinterface.h"
20#include "media/base/fakertp.h"
21#include "media/base/mediaconstants.h"
22#include "media/engine/fakewebrtccall.h"
23#include "media/engine/fakewebrtcvoiceengine.h"
24#include "media/engine/webrtcvoiceengine.h"
25#include "modules/audio_device/include/mock_audio_device.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "pc/channel.h"
28#include "rtc_base/arraysize.h"
29#include "rtc_base/byteorder.h"
30#include "rtc_base/safe_conversions.h"
31#include "rtc_base/scoped_ref_ptr.h"
32#include "test/field_trial.h"
33#include "test/gtest.h"
34#include "test/mock_audio_decoder_factory.h"
35#include "test/mock_audio_encoder_factory.h"
36#include "voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
peahb1c9d1d2017-07-25 15:45:24 -070038using testing::_;
kwiberg1c07c702017-03-27 07:15:49 -070039using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070040using testing::Return;
peahb1c9d1d2017-07-25 15:45:24 -070041using testing::ReturnPointee;
42using testing::SaveArg;
solenbergbc37fc82016-04-04 09:54:44 -070043using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020045namespace {
46
solenberg418b7d32017-06-13 00:38:27 -070047constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070048
deadbeef67cf2c12016-04-13 10:07:16 -070049const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
50const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070051const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070052const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
53const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070054const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
55const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080056const cricket::AudioCodec
57 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
58const cricket::AudioCodec
59 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
60
solenberg2100c0b2017-03-01 11:29:29 -080061const uint32_t kSsrc0 = 0;
62const uint32_t kSsrc1 = 1;
63const uint32_t kSsrcX = 0x99;
64const uint32_t kSsrcY = 0x17;
65const uint32_t kSsrcZ = 0x42;
66const uint32_t kSsrcW = 0x02;
67const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
solenberg971cab02016-06-14 10:02:41 -070069constexpr int kRtpHistoryMs = 5000;
70
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071class FakeVoEWrapper : public cricket::VoEWrapper {
72 public:
73 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070074 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075 }
76};
skvlad11a9cbf2016-10-07 11:53:05 -070077
solenberg76377c52017-02-21 00:54:31 -080078class MockTransmitMixer : public webrtc::voe::TransmitMixer {
79 public:
80 MockTransmitMixer() = default;
81 virtual ~MockTransmitMixer() = default;
82
83 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
84};
solenberg9a5f032222017-03-15 06:14:12 -070085
86void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
87 RTC_DCHECK(adm);
Niels Möller6f72f562017-10-19 13:15:17 +020088 EXPECT_CALL(*adm, AddRef()).Times(1);
89 EXPECT_CALL(*adm, Release())
90 .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenberg9a5f032222017-03-15 06:14:12 -070091#if !defined(WEBRTC_IOS)
92 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
93 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
94 ChannelType::kChannelBoth)).WillOnce(Return(0));
95#if defined(WEBRTC_WIN)
96 EXPECT_CALL(*adm, SetRecordingDevice(
97 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
98 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
99 .WillOnce(Return(0));
100#else
101 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
102#endif // #if defined(WEBRTC_WIN)
103 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
104 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
105 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
106 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
107#if defined(WEBRTC_WIN)
108 EXPECT_CALL(*adm, SetPlayoutDevice(
109 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
110 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
111 .WillOnce(Return(0));
112#else
113 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
114#endif // #if defined(WEBRTC_WIN)
115 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
116 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
117 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
118#endif // #if !defined(WEBRTC_IOS)
119 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
120 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
121 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
122 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
123}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200124} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000125
solenbergff976312016-03-30 23:28:51 -0700126// Tests that our stub library "works".
127TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700128 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700129 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700130 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
131 new rtc::RefCountedObject<
132 StrictMock<webrtc::test::MockAudioProcessing>>();
peahb1c9d1d2017-07-25 15:45:24 -0700133 webrtc::AudioProcessing::Config apm_config;
134 EXPECT_CALL(*apm, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config));
135 EXPECT_CALL(*apm, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -0700136 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
137 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
138 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800139 StrictMock<MockTransmitMixer> transmit_mixer;
140 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700141 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700142 EXPECT_FALSE(voe.IsInited());
143 {
ossuc54071d2016-08-17 02:45:41 -0700144 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700145 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700146 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700147 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700148 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700149 EXPECT_TRUE(voe.IsInited());
150 }
151 EXPECT_FALSE(voe.IsInited());
152}
153
deadbeef884f5852016-01-15 09:20:04 -0800154class FakeAudioSink : public webrtc::AudioSinkInterface {
155 public:
156 void OnData(const Data& audio) override {}
157};
158
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800159class FakeAudioSource : public cricket::AudioSource {
160 void SetSink(Sink* sink) override {}
161};
162
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163class WebRtcVoiceEngineTestFake : public testing::Test {
164 public:
stefanba4c0e42016-02-04 04:12:24 -0800165 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
166
167 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700168 : apm_(new rtc::RefCountedObject<
169 StrictMock<webrtc::test::MockAudioProcessing>>()),
170 apm_gc_(*apm_->gain_control()),
171 apm_ec_(*apm_->echo_cancellation()),
172 apm_ns_(*apm_->noise_suppression()),
173 apm_vd_(*apm_->voice_detection()),
174 call_(webrtc::Call::Config(&event_log_)),
175 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700176 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800177 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700178 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800179 // AudioProcessing.
peahb1c9d1d2017-07-25 15:45:24 -0700180 EXPECT_CALL(*apm_, GetConfig()).WillRepeatedly(ReturnPointee(&apm_config_));
181 EXPECT_CALL(*apm_, ApplyConfig(_)).WillRepeatedly(SaveArg<0>(&apm_config_));
peaha9cc40b2017-06-29 08:32:09 -0700182 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
183 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
184 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800185 // Default Options.
186 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
187 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
188 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
189 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
190 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
191 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
192 // Init does not overwrite default AGC config.
193 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
194 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
195 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
196 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
197 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
198 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700199 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800200 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700201 // factories. Those tests should probably be moved elsewhere.
202 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
203 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
204 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700205 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700206 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700207 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200208 send_parameters_.codecs.push_back(kPcmuCodec);
209 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800210 // Default Options.
211 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
solenberg8189b022016-06-14 12:13:00 -0700213
solenbergff976312016-03-30 23:28:51 -0700214 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700215 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700216 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
217 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200218 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000219 }
solenberg8189b022016-06-14 12:13:00 -0700220
solenbergff976312016-03-30 23:28:51 -0700221 bool SetupRecvStream() {
222 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700223 return false;
224 }
solenberg2100c0b2017-03-01 11:29:29 -0800225 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700226 }
solenberg8189b022016-06-14 12:13:00 -0700227
solenbergff976312016-03-30 23:28:51 -0700228 bool SetupSendStream() {
229 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000230 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000231 }
solenberg2100c0b2017-03-01 11:29:29 -0800232 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800233 return false;
234 }
peaha9cc40b2017-06-29 08:32:09 -0700235 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800236 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 }
solenberg8189b022016-06-14 12:13:00 -0700238
239 bool AddRecvStream(uint32_t ssrc) {
240 EXPECT_TRUE(channel_);
241 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
242 }
243
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000244 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700245 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700246 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800247 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
248 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700249 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800250 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251 }
solenberg8189b022016-06-14 12:13:00 -0700252
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700254 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000255 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 }
solenberg8189b022016-06-14 12:13:00 -0700257
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200258 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 }
261
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100262 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
263 const auto* send_stream = call_.GetAudioSendStream(ssrc);
264 EXPECT_TRUE(send_stream);
265 return *send_stream;
266 }
267
deadbeef884f5852016-01-15 09:20:04 -0800268 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
269 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
270 EXPECT_TRUE(recv_stream);
271 return *recv_stream;
272 }
273
solenberg3a941542015-11-16 07:34:50 -0800274 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800275 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800276 }
277
solenberg7add0582015-11-20 09:59:34 -0800278 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800279 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800280 }
281
solenberg059fb442016-10-26 05:12:24 -0700282 void SetSend(bool enable) {
283 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700284 if (enable) {
285 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
286 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
287 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700289 }
solenberg059fb442016-10-26 05:12:24 -0700290 channel_->SetSend(enable);
291 }
292
293 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700294 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700295 ASSERT_TRUE(channel_);
296 EXPECT_TRUE(channel_->SetSendParameters(params));
297 }
298
minyue6b825df2016-10-31 04:08:32 -0700299 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
300 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700301 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700302 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700303 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700304 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700305 }
306 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700307 }
308
solenbergffbbcac2016-11-17 05:25:37 -0800309 void TestInsertDtmf(uint32_t ssrc, bool caller,
310 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700311 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700313 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314 // send stream.
315 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800316 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000317 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000318
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700320 SetSendParameters(send_parameters_);
321 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800323 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800324 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700325 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000327
328 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700329 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800330 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000331 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800332 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000333 }
334
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800336 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100338 // Test send.
339 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800340 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100341 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800342 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800343 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800344 EXPECT_EQ(codec.id, telephone_event.payload_type);
345 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100346 EXPECT_EQ(2, telephone_event.event_code);
347 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000348 }
349
350 // Test that send bandwidth is set correctly.
351 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000352 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
353 // |expected_result| is the expected result from SetMaxSendBandwidth().
354 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700355 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
356 int max_bitrate,
357 bool expected_result,
358 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200359 cricket::AudioSendParameters parameters;
360 parameters.codecs.push_back(codec);
361 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700362 if (expected_result) {
363 SetSendParameters(parameters);
364 } else {
365 EXPECT_FALSE(channel_->SetSendParameters(parameters));
366 }
solenberg2100c0b2017-03-01 11:29:29 -0800367 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368 }
369
skvlade0d46372016-04-07 22:59:22 -0700370 // Sets the per-stream maximum bitrate limit for the specified SSRC.
371 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700372 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700373 EXPECT_EQ(1UL, parameters.encodings.size());
374
deadbeefe702b302017-02-04 12:09:01 -0800375 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700376 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700377 }
378
solenberg059fb442016-10-26 05:12:24 -0700379 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700380 cricket::AudioSendParameters send_parameters;
381 send_parameters.codecs.push_back(codec);
382 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700383 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700384 }
385
ossu20a4b3f2017-04-27 02:08:52 -0700386 void CheckSendCodecBitrate(int32_t ssrc,
387 const char expected_name[],
388 int expected_bitrate) {
389 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
390 EXPECT_EQ(expected_name, spec->format.name);
391 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700392 }
393
ossu20a4b3f2017-04-27 02:08:52 -0700394 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
395 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700396 }
397
minyue6b825df2016-10-31 04:08:32 -0700398 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
399 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
400 }
401
skvlade0d46372016-04-07 22:59:22 -0700402 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
403 int global_max,
404 int stream_max,
405 bool expected_result,
406 int expected_codec_bitrate) {
407 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800408 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700409
410 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700411 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800412 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700413
414 // Verify that reading back the parameters gives results
415 // consistent with the Set() result.
416 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800417 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700418 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
419 EXPECT_EQ(expected_result ? stream_max : -1,
420 resulting_parameters.encodings[0].max_bitrate_bps);
421
422 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800423 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700424 }
425
stefan13f1a0a2016-11-30 07:22:58 -0800426 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
427 int expected_min_bitrate_bps,
428 const char* start_bitrate_kbps,
429 int expected_start_bitrate_bps,
430 const char* max_bitrate_kbps,
431 int expected_max_bitrate_bps) {
432 EXPECT_TRUE(SetupSendStream());
433 auto& codecs = send_parameters_.codecs;
434 codecs.clear();
435 codecs.push_back(kOpusCodec);
436 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
437 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
438 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
439 SetSendParameters(send_parameters_);
440
441 EXPECT_EQ(expected_min_bitrate_bps,
442 call_.GetConfig().bitrate_config.min_bitrate_bps);
443 EXPECT_EQ(expected_start_bitrate_bps,
444 call_.GetConfig().bitrate_config.start_bitrate_bps);
445 EXPECT_EQ(expected_max_bitrate_bps,
446 call_.GetConfig().bitrate_config.max_bitrate_bps);
447 }
448
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000449 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700450 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000452 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800453 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000454
455 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700456 send_parameters_.extensions.push_back(
457 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700458 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800459 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000460
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000461 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200462 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700463 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800464 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000465
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000466 // Ensure extension is set properly.
467 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700468 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700469 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800470 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
471 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
472 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000473
solenberg7add0582015-11-20 09:59:34 -0800474 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000475 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800476 cricket::StreamParams::CreateLegacy(kSsrcY)));
477 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
478 call_.GetAudioSendStream(kSsrcY));
479 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
480 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
481 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000482
483 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200484 send_parameters_.codecs.push_back(kPcmuCodec);
485 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700486 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800487 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
488 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489 }
490
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000491 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700492 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800495 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000496
497 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700498 recv_parameters_.extensions.push_back(
499 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800500 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800501 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000502
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000503 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800504 recv_parameters_.extensions.clear();
505 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800506 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000507
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000508 // Ensure extension is set properly.
509 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700510 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800511 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800512 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
513 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
514 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000515
solenberg7add0582015-11-20 09:59:34 -0800516 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800517 EXPECT_TRUE(AddRecvStream(kSsrcY));
518 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
519 call_.GetAudioReceiveStream(kSsrcY));
520 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
521 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
522 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000523
524 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800525 recv_parameters_.extensions.clear();
526 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800527 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
528 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000529 }
530
solenberg85a04962015-10-27 03:35:21 -0700531 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
532 webrtc::AudioSendStream::Stats stats;
533 stats.local_ssrc = 12;
534 stats.bytes_sent = 345;
535 stats.packets_sent = 678;
536 stats.packets_lost = 9012;
537 stats.fraction_lost = 34.56f;
538 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800539 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700540 stats.ext_seqnum = 789;
541 stats.jitter_ms = 12;
542 stats.rtt_ms = 345;
543 stats.audio_level = 678;
544 stats.aec_quality_min = 9.01f;
545 stats.echo_delay_median_ms = 234;
546 stats.echo_delay_std_ms = 567;
547 stats.echo_return_loss = 890;
548 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700549 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800550 stats.residual_echo_likelihood_recent_max = 0.6f;
ivoce1198e02017-09-08 08:13:19 -0700551 stats.ana_statistics.bitrate_action_counter = rtc::Optional<uint32_t>(321);
552 stats.ana_statistics.channel_action_counter = rtc::Optional<uint32_t>(432);
553 stats.ana_statistics.dtx_action_counter = rtc::Optional<uint32_t>(543);
554 stats.ana_statistics.fec_action_counter = rtc::Optional<uint32_t>(654);
ivoc0d0b9122017-09-08 13:24:21 -0700555 stats.ana_statistics.frame_length_increase_counter =
ivoce1198e02017-09-08 08:13:19 -0700556 rtc::Optional<uint32_t>(765);
ivoc0d0b9122017-09-08 13:24:21 -0700557 stats.ana_statistics.frame_length_decrease_counter =
558 rtc::Optional<uint32_t>(876);
559 stats.ana_statistics.uplink_packet_loss_fraction =
560 rtc::Optional<float>(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";
hbos1acfbd22016-11-17 23:43:29 -0800618 stats.codec_payload_type = rtc::Optional<int>(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);
deadbeeffb2aced2017-01-06 23:05:37 -08001075 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(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;
1183 rtp_parameters.encodings[0].max_bitrate_bps =
1184 rtc::Optional<int>(kMaxBitrateBps);
1185 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1186
1187 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1188 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1189}
1190
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001191// Test that GetRtpReceiveParameters returns the currently configured codecs.
1192TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1193 EXPECT_TRUE(SetupRecvStream());
1194 cricket::AudioRecvParameters parameters;
1195 parameters.codecs.push_back(kIsacCodec);
1196 parameters.codecs.push_back(kPcmuCodec);
1197 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1198
1199 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001200 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001201 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1202 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1203 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1204}
1205
deadbeefcb443432016-12-12 11:12:36 -08001206// Test that GetRtpReceiveParameters returns an SSRC.
1207TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1208 EXPECT_TRUE(SetupRecvStream());
1209 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001210 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001211 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001212 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001213}
1214
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001215// Test that if we set/get parameters multiple times, we get the same results.
1216TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1217 EXPECT_TRUE(SetupRecvStream());
1218 cricket::AudioRecvParameters parameters;
1219 parameters.codecs.push_back(kIsacCodec);
1220 parameters.codecs.push_back(kPcmuCodec);
1221 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1222
1223 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001224 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225
1226 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001227 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001228
1229 // ... And this shouldn't change the params returned by
1230 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001231 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1232 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001233}
1234
deadbeef3bc15102017-04-20 19:25:07 -07001235// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1236// aren't signaled. It should return an empty "RtpEncodingParameters" when
1237// configured to receive an unsignaled stream and no packets have been received
1238// yet, and start returning the SSRC once a packet has been received.
1239TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1240 ASSERT_TRUE(SetupChannel());
1241 // Call necessary methods to configure receiving a default stream as
1242 // soon as it arrives.
1243 cricket::AudioRecvParameters parameters;
1244 parameters.codecs.push_back(kIsacCodec);
1245 parameters.codecs.push_back(kPcmuCodec);
1246 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1247
1248 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1249 // stream. Should return nothing.
1250 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1251
1252 // Set a sink for an unsignaled stream.
1253 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1254 // Value of "0" means "unsignaled stream".
1255 channel_->SetRawAudioSink(0, std::move(fake_sink));
1256
1257 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1258 // in this method means "unsignaled stream".
1259 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1260 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1261 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1262
1263 // Receive PCMU packet (SSRC=1).
1264 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1265
1266 // The |ssrc| member should still be unset.
1267 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1268 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1269 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1270}
1271
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001272// Test that we apply codecs properly.
1273TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001274 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001275 cricket::AudioSendParameters parameters;
1276 parameters.codecs.push_back(kIsacCodec);
1277 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001278 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001279 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001280 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001281 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001282 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1283 EXPECT_EQ(96, send_codec_spec.payload_type);
1284 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1285 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1286 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1287 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001288 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001289}
1290
ossu20a4b3f2017-04-27 02:08:52 -07001291// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1292// AudioSendStream.
1293TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001294 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001295 cricket::AudioSendParameters parameters;
1296 parameters.codecs.push_back(kIsacCodec);
1297 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001298 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001299 parameters.codecs[0].id = 96;
1300 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001301 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001302 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001303 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001304 // Calling SetSendCodec again with same codec which is already set.
1305 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001306 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001307 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001308}
1309
ossu20a4b3f2017-04-27 02:08:52 -07001310// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1311// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001312
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001313// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].clockrate = 50000;
1320 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321}
1322
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001323// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001325 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001326 cricket::AudioSendParameters parameters;
1327 parameters.codecs.push_back(kOpusCodec);
1328 parameters.codecs[0].bitrate = 0;
1329 parameters.codecs[0].channels = 0;
1330 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331}
1332
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001333// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001335 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001336 cricket::AudioSendParameters parameters;
1337 parameters.codecs.push_back(kOpusCodec);
1338 parameters.codecs[0].bitrate = 0;
1339 parameters.codecs[0].channels = 0;
1340 parameters.codecs[0].params["stereo"] = "1";
1341 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001342}
1343
1344// Test that if channel is 1 for opus and there's no stereo, we fail.
1345TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001346 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001347 cricket::AudioSendParameters parameters;
1348 parameters.codecs.push_back(kOpusCodec);
1349 parameters.codecs[0].bitrate = 0;
1350 parameters.codecs[0].channels = 1;
1351 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001352}
1353
1354// Test that if channel is 1 for opus and stereo=0, we fail.
1355TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001356 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001357 cricket::AudioSendParameters parameters;
1358 parameters.codecs.push_back(kOpusCodec);
1359 parameters.codecs[0].bitrate = 0;
1360 parameters.codecs[0].channels = 1;
1361 parameters.codecs[0].params["stereo"] = "0";
1362 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001363}
1364
1365// Test that if channel is 1 for opus and stereo=1, we fail.
1366TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001367 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001368 cricket::AudioSendParameters parameters;
1369 parameters.codecs.push_back(kOpusCodec);
1370 parameters.codecs[0].bitrate = 0;
1371 parameters.codecs[0].channels = 1;
1372 parameters.codecs[0].params["stereo"] = "1";
1373 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374}
1375
ossu20a4b3f2017-04-27 02:08:52 -07001376// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001378 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001379 cricket::AudioSendParameters parameters;
1380 parameters.codecs.push_back(kOpusCodec);
1381 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001382 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001383 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384}
1385
ossu20a4b3f2017-04-27 02:08:52 -07001386// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001388 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 cricket::AudioSendParameters parameters;
1390 parameters.codecs.push_back(kOpusCodec);
1391 parameters.codecs[0].bitrate = 0;
1392 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001393 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001394 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
ossu20a4b3f2017-04-27 02:08:52 -07001397// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001398TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001399 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 cricket::AudioSendParameters parameters;
1401 parameters.codecs.push_back(kOpusCodec);
1402 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001403 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001404 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001407
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001408 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001409 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001410 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001411}
1412
ossu20a4b3f2017-04-27 02:08:52 -07001413// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001415 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 cricket::AudioSendParameters parameters;
1417 parameters.codecs.push_back(kOpusCodec);
1418 parameters.codecs[0].bitrate = 0;
1419 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001420 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001421 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422}
1423
ossu20a4b3f2017-04-27 02:08:52 -07001424// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001425TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001426 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001427 cricket::AudioSendParameters parameters;
1428 parameters.codecs.push_back(kOpusCodec);
1429 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001430 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001431 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001433 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001434
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001435 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001436 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001437 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001438}
1439
ossu20a4b3f2017-04-27 02:08:52 -07001440// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001442 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001443 cricket::AudioSendParameters parameters;
1444 parameters.codecs.push_back(kOpusCodec);
1445 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001446 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001447 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1448 EXPECT_EQ(111, spec.payload_type);
1449 EXPECT_EQ(96000, spec.target_bitrate_bps);
1450 EXPECT_EQ("opus", spec.format.name);
1451 EXPECT_EQ(2, spec.format.num_channels);
1452 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453}
1454
ossu20a4b3f2017-04-27 02:08:52 -07001455// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001457 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001458 cricket::AudioSendParameters parameters;
1459 parameters.codecs.push_back(kOpusCodec);
1460 parameters.codecs[0].bitrate = 30000;
1461 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001462 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001463 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464}
1465
ossu20a4b3f2017-04-27 02:08:52 -07001466// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001467TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001468 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001469 cricket::AudioSendParameters parameters;
1470 parameters.codecs.push_back(kOpusCodec);
1471 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001472 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001473 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474}
1475
ossu20a4b3f2017-04-27 02:08:52 -07001476// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001478 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001479 cricket::AudioSendParameters parameters;
1480 parameters.codecs.push_back(kOpusCodec);
1481 parameters.codecs[0].bitrate = 30000;
1482 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001483 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001484 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001485}
1486
stefan13f1a0a2016-11-30 07:22:58 -08001487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1488 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1489 200000);
1490}
1491
1492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1493 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1494}
1495
1496TEST_F(WebRtcVoiceEngineTestFake,
1497 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1498 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1499}
1500
1501TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1502 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1503}
1504
1505TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001506 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001507 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1508 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001509 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001510 SetSendParameters(send_parameters_);
1511 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1512 << "Setting max bitrate should keep previous min bitrate.";
1513 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1514 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001515 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001516}
1517
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001518// Test that we can enable NACK with opus as caller.
1519TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001520 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 cricket::AudioSendParameters parameters;
1522 parameters.codecs.push_back(kOpusCodec);
1523 parameters.codecs[0].AddFeedbackParam(
1524 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1525 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001526 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001527 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001528 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001529}
1530
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001531// Test that we can enable NACK with opus as callee.
1532TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001533 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001534 cricket::AudioSendParameters parameters;
1535 parameters.codecs.push_back(kOpusCodec);
1536 parameters.codecs[0].AddFeedbackParam(
1537 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1538 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001539 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001540 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001541 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001543
1544 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001545 cricket::StreamParams::CreateLegacy(kSsrcX)));
1546 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001547}
1548
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001549// Test that we can enable NACK on receive streams.
1550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001551 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001552 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001553 cricket::AudioSendParameters parameters;
1554 parameters.codecs.push_back(kOpusCodec);
1555 parameters.codecs[0].AddFeedbackParam(
1556 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1557 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001558 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1559 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001560 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1562 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563}
1564
1565// Test that we can disable NACK.
1566TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001567 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001568 cricket::AudioSendParameters parameters;
1569 parameters.codecs.push_back(kOpusCodec);
1570 parameters.codecs[0].AddFeedbackParam(
1571 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1572 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001573 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001574 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001576 parameters.codecs.clear();
1577 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001579 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001580}
1581
1582// Test that we can disable NACK on receive streams.
1583TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001584 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001585 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001586 cricket::AudioSendParameters parameters;
1587 parameters.codecs.push_back(kOpusCodec);
1588 parameters.codecs[0].AddFeedbackParam(
1589 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1590 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001591 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001592 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1593 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001594
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001595 parameters.codecs.clear();
1596 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001597 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001598 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1599 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001600}
1601
1602// Test that NACK is enabled on a new receive stream.
1603TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001604 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001605 cricket::AudioSendParameters parameters;
1606 parameters.codecs.push_back(kIsacCodec);
1607 parameters.codecs.push_back(kCn16000Codec);
1608 parameters.codecs[0].AddFeedbackParam(
1609 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1610 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001611 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001612 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613
solenberg2100c0b2017-03-01 11:29:29 -08001614 EXPECT_TRUE(AddRecvStream(kSsrcY));
1615 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1616 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1617 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618}
1619
stefanba4c0e42016-02-04 04:12:24 -08001620TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001621 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001622 cricket::AudioSendParameters send_parameters;
1623 send_parameters.codecs.push_back(kOpusCodec);
1624 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001626
1627 cricket::AudioRecvParameters recv_parameters;
1628 recv_parameters.codecs.push_back(kIsacCodec);
1629 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001630 EXPECT_TRUE(AddRecvStream(kSsrcX));
1631 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001632 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001633 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001634
ossudedfd282016-06-14 07:12:39 -07001635 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001636 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001637 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001638 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001639 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001640}
1641
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001642// Test that we can switch back and forth between Opus and ISAC with CN.
1643TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001644 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001645
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters opus_parameters;
1647 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001649 {
ossu20a4b3f2017-04-27 02:08:52 -07001650 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1651 EXPECT_EQ(111, spec.payload_type);
1652 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001653 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001654
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001655 cricket::AudioSendParameters isac_parameters;
1656 isac_parameters.codecs.push_back(kIsacCodec);
1657 isac_parameters.codecs.push_back(kCn16000Codec);
1658 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001660 {
ossu20a4b3f2017-04-27 02:08:52 -07001661 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1662 EXPECT_EQ(103, spec.payload_type);
1663 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001664 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665
solenberg059fb442016-10-26 05:12:24 -07001666 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001667 {
ossu20a4b3f2017-04-27 02:08:52 -07001668 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1669 EXPECT_EQ(111, spec.payload_type);
1670 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001671 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672}
1673
1674// Test that we handle various ways of specifying bitrate.
1675TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001676 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001677 cricket::AudioSendParameters parameters;
1678 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001679 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001680 {
ossu20a4b3f2017-04-27 02:08:52 -07001681 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1682 EXPECT_EQ(103, spec.payload_type);
1683 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1684 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001685 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001686
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001687 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001688 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001689 {
ossu20a4b3f2017-04-27 02:08:52 -07001690 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1691 EXPECT_EQ(103, spec.payload_type);
1692 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1693 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001694 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001697 {
ossu20a4b3f2017-04-27 02:08:52 -07001698 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1699 EXPECT_EQ(103, spec.payload_type);
1700 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1701 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001702 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001704 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001706 {
ossu20a4b3f2017-04-27 02:08:52 -07001707 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1708 EXPECT_EQ(0, spec.payload_type);
1709 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1710 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001711 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001712
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001713 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001715 {
ossu20a4b3f2017-04-27 02:08:52 -07001716 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1717 EXPECT_EQ(0, spec.payload_type);
1718 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1719 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001720 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001722 parameters.codecs[0] = kOpusCodec;
1723 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001724 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001725 {
ossu20a4b3f2017-04-27 02:08:52 -07001726 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1727 EXPECT_EQ(111, spec.payload_type);
1728 EXPECT_STREQ("opus", spec.format.name.c_str());
1729 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001730 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731}
1732
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001733// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001735 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 cricket::AudioSendParameters parameters;
1737 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001738}
1739
1740// Test that we can set send codecs even with telephone-event codec as the first
1741// one on the list.
1742TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001743 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001745 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001746 parameters.codecs.push_back(kIsacCodec);
1747 parameters.codecs.push_back(kPcmuCodec);
1748 parameters.codecs[0].id = 98; // DTMF
1749 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(96, spec.payload_type);
1753 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001754 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001755}
1756
solenberg31642aa2016-03-14 08:00:37 -07001757// Test that payload type range is limited for telephone-event codec.
1758TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001759 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001760 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001761 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001762 parameters.codecs.push_back(kIsacCodec);
1763 parameters.codecs[0].id = 0; // DTMF
1764 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001765 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001766 EXPECT_TRUE(channel_->CanInsertDtmf());
1767 parameters.codecs[0].id = 128; // DTMF
1768 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1769 EXPECT_FALSE(channel_->CanInsertDtmf());
1770 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001771 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001772 EXPECT_TRUE(channel_->CanInsertDtmf());
1773 parameters.codecs[0].id = -1; // DTMF
1774 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1775 EXPECT_FALSE(channel_->CanInsertDtmf());
1776}
1777
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001778// Test that we can set send codecs even with CN codec as the first
1779// one on the list.
1780TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001781 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001782 cricket::AudioSendParameters parameters;
1783 parameters.codecs.push_back(kCn16000Codec);
1784 parameters.codecs.push_back(kIsacCodec);
1785 parameters.codecs.push_back(kPcmuCodec);
1786 parameters.codecs[0].id = 98; // wideband CN
1787 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001788 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001789 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1790 EXPECT_EQ(96, send_codec_spec.payload_type);
1791 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001792 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793}
1794
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001795// Test that we set VAD and DTMF types correctly as caller.
1796TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001797 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001798 cricket::AudioSendParameters parameters;
1799 parameters.codecs.push_back(kIsacCodec);
1800 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 parameters.codecs.push_back(kCn16000Codec);
1803 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001804 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 parameters.codecs[0].id = 96;
1806 parameters.codecs[2].id = 97; // wideband CN
1807 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001808 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001809 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1810 EXPECT_EQ(96, send_codec_spec.payload_type);
1811 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1812 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001813 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001814 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815}
1816
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001817// Test that we set VAD and DTMF types correctly as callee.
1818TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001819 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001820 cricket::AudioSendParameters parameters;
1821 parameters.codecs.push_back(kIsacCodec);
1822 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001823 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 parameters.codecs.push_back(kCn16000Codec);
1825 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001826 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 parameters.codecs[0].id = 96;
1828 parameters.codecs[2].id = 97; // wideband CN
1829 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001831 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001832 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001833
ossu20a4b3f2017-04-27 02:08:52 -07001834 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1835 EXPECT_EQ(96, send_codec_spec.payload_type);
1836 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1837 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001838 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001839 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001840}
1841
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842// Test that we only apply VAD if we have a CN codec that matches the
1843// send codec clockrate.
1844TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001845 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001846 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001847 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 parameters.codecs.push_back(kIsacCodec);
1849 parameters.codecs.push_back(kCn16000Codec);
1850 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001851 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001852 {
ossu20a4b3f2017-04-27 02:08:52 -07001853 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1854 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1855 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001856 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001857 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001858 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001860 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001861 {
ossu20a4b3f2017-04-27 02:08:52 -07001862 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1863 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1864 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001865 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001866 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001867 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001868 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001869 {
ossu20a4b3f2017-04-27 02:08:52 -07001870 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1871 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1872 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001873 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001874 }
Brave Yao5225dd82015-03-26 07:39:19 +08001875 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001876 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001877 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001878 {
ossu20a4b3f2017-04-27 02:08:52 -07001879 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1880 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1881 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001882 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001883}
1884
1885// Test that we perform case-insensitive matching of codec names.
1886TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001887 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 cricket::AudioSendParameters parameters;
1889 parameters.codecs.push_back(kIsacCodec);
1890 parameters.codecs.push_back(kPcmuCodec);
1891 parameters.codecs.push_back(kCn16000Codec);
1892 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001893 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001894 parameters.codecs[0].name = "iSaC";
1895 parameters.codecs[0].id = 96;
1896 parameters.codecs[2].id = 97; // wideband CN
1897 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001898 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001899 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1900 EXPECT_EQ(96, send_codec_spec.payload_type);
1901 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1902 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001903 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001904 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001905}
1906
stefanba4c0e42016-02-04 04:12:24 -08001907class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1908 public:
1909 WebRtcVoiceEngineWithSendSideBweTest()
1910 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1911};
1912
1913TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1914 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001915 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001916 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001917 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1918 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1919 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001920 extension.id);
1921 return;
1922 }
1923 }
1924 FAIL() << "Transport sequence number extension not in header-extension list.";
1925}
1926
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001927// Test support for audio level header extension.
1928TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001929 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001930}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001931TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001932 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001933}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001934
solenbergd4adce42016-11-17 06:26:52 -08001935// Test support for transport sequence number header extension.
1936TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1937 TestSetSendRtpHeaderExtensions(
1938 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001939}
solenbergd4adce42016-11-17 06:26:52 -08001940TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1941 TestSetRecvRtpHeaderExtensions(
1942 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001943}
1944
solenberg1ac56142015-10-13 03:58:19 -07001945// Test that we can create a channel and start sending on it.
1946TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001947 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001948 SetSendParameters(send_parameters_);
1949 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001950 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001951 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001952 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001953}
1954
1955// Test that a channel will send if and only if it has a source and is enabled
1956// for sending.
1957TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001958 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001960 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001961 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001962 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1963 SetAudioSend(kSsrcX, true, &fake_source_);
1964 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1965 SetAudioSend(kSsrcX, true, nullptr);
1966 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001967}
1968
solenberg94218532016-06-16 10:53:22 -07001969// Test that a channel is muted/unmuted.
1970TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1971 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001972 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001973 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1974 SetAudioSend(kSsrcX, true, nullptr);
1975 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1976 SetAudioSend(kSsrcX, false, nullptr);
1977 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001978}
1979
solenberg6d6e7c52016-04-13 09:07:30 -07001980// Test that SetSendParameters() does not alter a stream's send state.
1981TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1982 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001983 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001984
1985 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001986 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001987 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001988
1989 // Changing RTP header extensions will recreate the AudioSendStream.
1990 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001991 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001993 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001994
1995 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001996 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001997 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001998
1999 // Changing RTP header extensions will recreate the AudioSendStream.
2000 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002001 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002002 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002003}
2004
solenberg1ac56142015-10-13 03:58:19 -07002005// Test that we can create a channel and start playing out on it.
2006TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002007 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002008 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002009 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002010 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002011 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002012 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002013}
2014
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015// Test that we can add and remove send streams.
2016TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2017 SetupForMultiSendStream();
2018
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002020 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002021
solenbergc96df772015-10-21 13:01:53 -07002022 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002023 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002024 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002025 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002026 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002027 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002028 }
tfarina5237aaf2015-11-10 23:44:30 -08002029 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002030
solenbergc96df772015-10-21 13:01:53 -07002031 // Delete the send streams.
2032 for (uint32_t ssrc : kSsrcs4) {
2033 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002034 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002035 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 }
solenbergc96df772015-10-21 13:01:53 -07002037 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038}
2039
2040// Test SetSendCodecs correctly configure the codecs in all send streams.
2041TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2042 SetupForMultiSendStream();
2043
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002045 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002047 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 }
2049
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002050 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002052 parameters.codecs.push_back(kIsacCodec);
2053 parameters.codecs.push_back(kCn16000Codec);
2054 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002055 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002056
2057 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002058 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002059 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2060 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002061 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2062 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2063 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002064 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002065 }
2066
minyue7a973442016-10-20 03:27:12 -07002067 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002068 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002069 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002070 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002071 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2072 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002073 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2074 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2075 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002076 }
2077}
2078
2079// Test we can SetSend on all send streams correctly.
2080TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2081 SetupForMultiSendStream();
2082
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002083 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002084 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002085 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002086 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002087 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002088 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002089 }
2090
2091 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002092 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002093 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002094 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002095 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002096 }
2097
2098 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002099 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002100 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002101 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002102 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002103 }
2104}
2105
2106// Test we can set the correct statistics on all send streams.
2107TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2108 SetupForMultiSendStream();
2109
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002110 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002111 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002112 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002113 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002114 }
solenberg85a04962015-10-27 03:35:21 -07002115
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002116 // Create a receive stream to check that none of the send streams end up in
2117 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002118 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002119
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002120 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002121 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002122 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002123 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124
solenberg85a04962015-10-27 03:35:21 -07002125 // Check stats for the added streams.
2126 {
2127 cricket::VoiceMediaInfo info;
2128 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002129
solenberg85a04962015-10-27 03:35:21 -07002130 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002131 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002132 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002133 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002134 }
hbos1acfbd22016-11-17 23:43:29 -08002135 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002136
2137 // We have added one receive stream. We should see empty stats.
2138 EXPECT_EQ(info.receivers.size(), 1u);
2139 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002140 }
solenberg1ac56142015-10-13 03:58:19 -07002141
solenberg2100c0b2017-03-01 11:29:29 -08002142 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002143 {
2144 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002145 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002146 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002147 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002148 EXPECT_EQ(0u, info.receivers.size());
2149 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002150
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002151 // Deliver a new packet - a default receive stream should be created and we
2152 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002153 {
2154 cricket::VoiceMediaInfo info;
2155 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2156 SetAudioReceiveStreamStats();
2157 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002158 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002159 EXPECT_EQ(1u, info.receivers.size());
2160 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002161 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002162 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002163}
2164
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002165// Test that we can add and remove receive streams, and do proper send/playout.
2166// We can receive on multiple streams while sending one stream.
2167TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002168 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169
solenberg1ac56142015-10-13 03:58:19 -07002170 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002171 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002172 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002173
solenberg1ac56142015-10-13 03:58:19 -07002174 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002175 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002176 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002177 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002178
solenberg1ac56142015-10-13 03:58:19 -07002179 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002180 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181
2182 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002183 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2184 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2185 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002186
2187 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002188 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002189 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002190
2191 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002192 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002193 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2194 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002195
aleloi84ef6152016-08-04 05:28:21 -07002196 // Restart playout and make sure recv streams are played out.
2197 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002198 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2199 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002200
aleloi84ef6152016-08-04 05:28:21 -07002201 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002202 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2203 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204}
2205
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002206// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002207// and start sending on it.
2208TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002209 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002210 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2211 EXPECT_CALL(apm_gc_,
2212 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002213 SetSendParameters(send_parameters_);
2214 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002215 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002216 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002217 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218}
2219
wu@webrtc.org97077a32013-10-25 21:18:33 +00002220TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002221 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002222 EXPECT_CALL(adm_,
2223 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002224 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2225 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002226 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2227 send_parameters_.options.tx_agc_digital_compression_gain =
2228 rtc::Optional<uint16_t>(9);
2229 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2230 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002231 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2232 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2233 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002234 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002235
2236 // Check interaction with adjust_agc_delta. Both should be respected, for
2237 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002238 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002239 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002240 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002241}
2242
wu@webrtc.org97077a32013-10-25 21:18:33 +00002243TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002244 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002245 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2246 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002247 send_parameters_.options.recording_sample_rate =
2248 rtc::Optional<uint32_t>(48000);
2249 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002250 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002251}
2252
minyue6b825df2016-10-31 04:08:32 -07002253TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2254 EXPECT_TRUE(SetupSendStream());
2255 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2256 send_parameters_.options.audio_network_adaptor_config =
2257 rtc::Optional<std::string>("1234");
2258 SetSendParameters(send_parameters_);
2259 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002260 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002261}
2262
2263TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2264 EXPECT_TRUE(SetupSendStream());
2265 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2266 send_parameters_.options.audio_network_adaptor_config =
2267 rtc::Optional<std::string>("1234");
2268 SetSendParameters(send_parameters_);
2269 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002270 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002271 cricket::AudioOptions options;
2272 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002273 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002274 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002275}
2276
2277TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2278 EXPECT_TRUE(SetupSendStream());
2279 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2280 send_parameters_.options.audio_network_adaptor_config =
2281 rtc::Optional<std::string>("1234");
2282 SetSendParameters(send_parameters_);
2283 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002284 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002285 const int initial_num = call_.GetNumCreatedSendStreams();
2286 cricket::AudioOptions options;
2287 options.audio_network_adaptor = rtc::Optional<bool>();
2288 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2289 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002290 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002291 // AudioSendStream not expected to be recreated.
2292 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2293 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002294 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002295}
2296
michaelt6672b262017-01-11 10:17:59 -08002297class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2298 : public WebRtcVoiceEngineTestFake {
2299 public:
2300 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2301 : WebRtcVoiceEngineTestFake(
2302 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2303 "Enabled/") {}
2304};
2305
2306TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2307 EXPECT_TRUE(SetupSendStream());
2308 cricket::AudioSendParameters parameters;
2309 parameters.codecs.push_back(kOpusCodec);
2310 SetSendParameters(parameters);
2311 const int initial_num = call_.GetNumCreatedSendStreams();
2312 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2313
2314 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2315 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002316 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2317 constexpr int kMinOverheadBps =
2318 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002319
2320 constexpr int kOpusMinBitrateBps = 6000;
2321 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002322 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002323 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002324 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002325 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002326
2327 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2328 parameters.options.audio_network_adaptor_config =
2329 rtc::Optional<std::string>("1234");
2330 SetSendParameters(parameters);
2331
ossu11bfc532017-02-16 05:37:06 -08002332 constexpr int kMinOverheadWithAnaBps =
2333 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002334
2335 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002336 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002337
minyuececec102017-03-27 13:04:25 -07002338 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002339 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002340}
2341
minyuececec102017-03-27 13:04:25 -07002342// This test is similar to
2343// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2344// additional field trial.
2345TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2346 SetRtpSendParameterUpdatesMaxBitrate) {
2347 EXPECT_TRUE(SetupSendStream());
2348 cricket::AudioSendParameters send_parameters;
2349 send_parameters.codecs.push_back(kOpusCodec);
2350 SetSendParameters(send_parameters);
2351
2352 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2353 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2354 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2355
2356 constexpr int kMaxBitrateBps = 6000;
2357 rtp_parameters.encodings[0].max_bitrate_bps =
2358 rtc::Optional<int>(kMaxBitrateBps);
2359 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2360
2361 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2362#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2363 constexpr int kMinOverhead = 3333;
2364#else
2365 constexpr int kMinOverhead = 6666;
2366#endif
2367 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2368}
2369
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002370// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002371// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002372TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002373 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002374 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002375}
2376
2377TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2378 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002379 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002380 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002381 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002382 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002383 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002384 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002385 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002386
solenberg85a04962015-10-27 03:35:21 -07002387 // Check stats for the added streams.
2388 {
2389 cricket::VoiceMediaInfo info;
2390 EXPECT_EQ(true, channel_->GetStats(&info));
2391
2392 // We have added one send stream. We should see the stats we've set.
2393 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002394 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002395 // We have added one receive stream. We should see empty stats.
2396 EXPECT_EQ(info.receivers.size(), 1u);
2397 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2398 }
solenberg1ac56142015-10-13 03:58:19 -07002399
solenberg566ef242015-11-06 15:34:49 -08002400 // Start sending - this affects some reported stats.
2401 {
2402 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002403 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002404 EXPECT_EQ(true, channel_->GetStats(&info));
2405 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002406 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002407 }
2408
solenberg2100c0b2017-03-01 11:29:29 -08002409 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002410 {
2411 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002412 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002413 EXPECT_EQ(true, channel_->GetStats(&info));
2414 EXPECT_EQ(1u, info.senders.size());
2415 EXPECT_EQ(0u, info.receivers.size());
2416 }
solenberg1ac56142015-10-13 03:58:19 -07002417
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002418 // Deliver a new packet - a default receive stream should be created and we
2419 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002420 {
2421 cricket::VoiceMediaInfo info;
2422 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2423 SetAudioReceiveStreamStats();
2424 EXPECT_EQ(true, channel_->GetStats(&info));
2425 EXPECT_EQ(1u, info.senders.size());
2426 EXPECT_EQ(1u, info.receivers.size());
2427 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002428 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002429 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002430}
2431
2432// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002433// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002434TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002435 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002436 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2437 EXPECT_TRUE(AddRecvStream(kSsrcY));
2438 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439}
2440
2441// Test that the local SSRC is the same on sending and receiving channels if the
2442// receive channel is created before the send channel.
2443TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002444 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002445 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002447 cricket::StreamParams::CreateLegacy(kSsrcX)));
2448 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2449 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450}
2451
2452// Test that we can properly receive packets.
2453TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002454 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002455 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002456 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002457
2458 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2459 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460}
2461
2462// Test that we can properly receive packets on multiple streams.
2463TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002464 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002465 const uint32_t ssrc1 = 1;
2466 const uint32_t ssrc2 = 2;
2467 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002468 EXPECT_TRUE(AddRecvStream(ssrc1));
2469 EXPECT_TRUE(AddRecvStream(ssrc2));
2470 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002472 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002473 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002475 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476 }
mflodman3d7db262016-04-29 00:57:13 -07002477
2478 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2479 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2480 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2481
2482 EXPECT_EQ(s1.received_packets(), 0);
2483 EXPECT_EQ(s2.received_packets(), 0);
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[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002487 EXPECT_EQ(s1.received_packets(), 0);
2488 EXPECT_EQ(s2.received_packets(), 0);
2489 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002490
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002491 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002492 EXPECT_EQ(s1.received_packets(), 1);
2493 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2494 EXPECT_EQ(s2.received_packets(), 0);
2495 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002496
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002498 EXPECT_EQ(s1.received_packets(), 1);
2499 EXPECT_EQ(s2.received_packets(), 1);
2500 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2501 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002502
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002504 EXPECT_EQ(s1.received_packets(), 1);
2505 EXPECT_EQ(s2.received_packets(), 1);
2506 EXPECT_EQ(s3.received_packets(), 1);
2507 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002508
mflodman3d7db262016-04-29 00:57:13 -07002509 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2510 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2511 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002512}
2513
solenberg2100c0b2017-03-01 11:29:29 -08002514// Test that receiving on an unsignaled stream works (a stream is created).
2515TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002516 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002517 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2518
solenberg7e63ef02015-11-20 00:19:43 -08002519 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002520
2521 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002522 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2523 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002524}
2525
solenberg2100c0b2017-03-01 11:29:29 -08002526// Test that receiving N unsignaled stream works (streams will be created), and
2527// that packets are forwarded to them all.
2528TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002529 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002530 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002531 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2532
solenberg2100c0b2017-03-01 11:29:29 -08002533 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002534 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002535 rtc::SetBE32(&packet[8], ssrc);
2536 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002537
solenberg2100c0b2017-03-01 11:29:29 -08002538 // Verify we have one new stream for each loop iteration.
2539 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002540 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2541 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002542 }
mflodman3d7db262016-04-29 00:57:13 -07002543
solenberg2100c0b2017-03-01 11:29:29 -08002544 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002545 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002546 rtc::SetBE32(&packet[8], ssrc);
2547 DeliverPacket(packet, sizeof(packet));
2548
solenbergebb349d2017-03-13 05:46:15 -07002549 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002550 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2551 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2552 }
2553
2554 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2555 constexpr uint32_t kAnotherSsrc = 667;
2556 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002557 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002558
2559 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002560 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002561 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002562 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002563 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2564 EXPECT_EQ(2, streams[i]->received_packets());
2565 }
2566 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2567 EXPECT_EQ(1, streams[i]->received_packets());
2568 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002569 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002570}
2571
solenberg2100c0b2017-03-01 11:29:29 -08002572// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002573// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002574TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002575 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002576 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002577 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2578
2579 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002580 const uint32_t signaled_ssrc = 1;
2581 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002582 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002583 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002584 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2585 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002586 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002587
2588 // Note that the first unknown SSRC cannot be 0, because we only support
2589 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002590 const uint32_t unsignaled_ssrc = 7011;
2591 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002592 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002593 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2594 packet, sizeof(packet)));
2595 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2596
2597 DeliverPacket(packet, sizeof(packet));
2598 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2599
2600 rtc::SetBE32(&packet[8], signaled_ssrc);
2601 DeliverPacket(packet, sizeof(packet));
2602 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2603 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002604}
2605
solenberg4904fb62017-02-17 12:01:14 -08002606// Two tests to verify that adding a receive stream with the same SSRC as a
2607// previously added unsignaled stream will only recreate underlying stream
2608// objects if the stream parameters have changed.
2609TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2610 EXPECT_TRUE(SetupChannel());
2611
2612 // Spawn unsignaled stream with SSRC=1.
2613 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2614 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2615 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2616 sizeof(kPcmuFrame)));
2617
2618 // Verify that the underlying stream object in Call is not recreated when a
2619 // stream with SSRC=1 is added.
2620 const auto& streams = call_.GetAudioReceiveStreams();
2621 EXPECT_EQ(1, streams.size());
2622 int audio_receive_stream_id = streams.front()->id();
2623 EXPECT_TRUE(AddRecvStream(1));
2624 EXPECT_EQ(1, streams.size());
2625 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2626}
2627
2628TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2629 EXPECT_TRUE(SetupChannel());
2630
2631 // Spawn unsignaled stream with SSRC=1.
2632 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2633 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2634 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2635 sizeof(kPcmuFrame)));
2636
2637 // Verify that the underlying stream object in Call *is* recreated when a
2638 // stream with SSRC=1 is added, and which has changed stream parameters.
2639 const auto& streams = call_.GetAudioReceiveStreams();
2640 EXPECT_EQ(1, streams.size());
2641 int audio_receive_stream_id = streams.front()->id();
2642 cricket::StreamParams stream_params;
2643 stream_params.ssrcs.push_back(1);
2644 stream_params.sync_label = "sync_label";
2645 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2646 EXPECT_EQ(1, streams.size());
2647 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2648}
2649
solenberg0a617e22015-10-20 15:49:38 -07002650// Test that we properly handle failures to add a receive stream.
2651TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002652 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002654 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655}
2656
solenberg0a617e22015-10-20 15:49:38 -07002657// Test that we properly handle failures to add a send stream.
2658TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002659 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002660 voe_.set_fail_create_channel(true);
2661 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2662}
2663
solenberg1ac56142015-10-13 03:58:19 -07002664// Test that AddRecvStream creates new stream.
2665TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002666 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002667 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002668 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002669 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002670}
2671
2672// Test that after adding a recv stream, we do not decode more codecs than
2673// those previously passed into SetRecvCodecs.
2674TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002675 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002676 cricket::AudioRecvParameters parameters;
2677 parameters.codecs.push_back(kIsacCodec);
2678 parameters.codecs.push_back(kPcmuCodec);
2679 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002680 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002681 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2682 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2683 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002684}
2685
2686// Test that we properly clean up any streams that were added, even if
2687// not explicitly removed.
2688TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002689 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002690 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002691 EXPECT_TRUE(AddRecvStream(1));
2692 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2694 delete channel_;
2695 channel_ = NULL;
2696 EXPECT_EQ(0, voe_.GetNumChannels());
2697}
2698
wu@webrtc.org78187522013-10-07 23:32:02 +00002699TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002700 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002701 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002702}
2703
2704TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002705 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002706 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002707 // Manually delete channel to simulate a failure.
2708 int channel = voe_.GetLastChannel();
2709 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2710 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002711 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002712 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002713 EXPECT_NE(channel, new_channel);
2714 // The last created channel is deleted too.
2715 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002716}
2717
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002718// Test the InsertDtmf on default send stream as caller.
2719TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002720 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721}
2722
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002723// Test the InsertDtmf on default send stream as callee
2724TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002725 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002726}
2727
2728// Test the InsertDtmf on specified send stream as caller.
2729TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002730 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002731}
2732
2733// Test the InsertDtmf on specified send stream as callee.
2734TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002735 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002736}
2737
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002738TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002739 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002740 EXPECT_CALL(adm_,
2741 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2742 EXPECT_CALL(adm_,
2743 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2744 EXPECT_CALL(adm_,
2745 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002746
solenberg246b8172015-12-08 09:50:23 -08002747 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2748 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749
solenberg246b8172015-12-08 09:50:23 -08002750 // Nothing set in AudioOptions, so everything should be as default.
2751 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002752 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002753 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002754 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2755 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002756
2757 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002758 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2759 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002760 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002761 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762
2763 // Turn echo cancellation back on, with settings, and make sure
2764 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002765 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2766 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002767 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002768 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002769
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002770 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2771 // control.
solenberg76377c52017-02-21 00:54:31 -08002772 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002774 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002775 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002776
2777 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002778 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2779 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002780 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2781 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2782 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002783 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002784
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002785 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002786 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2787 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002788 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002789 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002790
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002792 EXPECT_CALL(adm_, SetAGC(false)).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(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002796 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002797 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002798
2799 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002800 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2801 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2802 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2803 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002804 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2805 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002806 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002807
2808 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002809 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2810 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2811 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2812 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2813 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2814 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2815 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002816 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2817 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2818 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2819 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002820 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002821 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002822
solenberg1ac56142015-10-13 03:58:19 -07002823 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002824 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2825 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2828 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2829 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2830 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002831 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832}
2833
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002834TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002835 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002836 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002837 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002838 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002839 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002840 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002841 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002842 EXPECT_CALL(adm_,
2843 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2844 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2845 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peahb1c9d1d2017-07-25 15:45:24 -07002846 webrtc::AudioProcessing::Config apm_config;
2847 EXPECT_CALL(*apm_, GetConfig())
2848 .Times(10)
2849 .WillRepeatedly(ReturnPointee(&apm_config));
2850 EXPECT_CALL(*apm_, ApplyConfig(_))
2851 .Times(10)
2852 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002853 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002854
kwiberg686a8ef2016-02-26 03:00:35 -08002855 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002856 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002857 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002858 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002859 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002860 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002861
2862 // Have to add a stream to make SetSend work.
2863 cricket::StreamParams stream1;
2864 stream1.ssrcs.push_back(1);
2865 channel1->AddSendStream(stream1);
2866 cricket::StreamParams stream2;
2867 stream2.ssrcs.push_back(2);
2868 channel2->AddSendStream(stream2);
2869
2870 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002871 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002872 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2873 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2874 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002875 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2876 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2877 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2878 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2879 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002880 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002882 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002883 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002884
2885 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002886 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002887 parameters_options_no_ns.options.noise_suppression =
2888 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002889 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2890 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2891 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2892 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2893 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002894 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002895 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002896 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2897 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2898 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002899 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900
2901 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002902 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002903 parameters_options_no_agc.options.auto_gain_control =
2904 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002905 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2906 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2907 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2908 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2909 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002910 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002911 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2912 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2913 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002914 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915
solenberg76377c52017-02-21 00:54:31 -08002916 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2917 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2918 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2919 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2920 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002921 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922
solenberg76377c52017-02-21 00:54:31 -08002923 EXPECT_CALL(adm_, SetAGC(true)).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(true)).WillOnce(Return(0));
2927 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002928 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002929
solenberg76377c52017-02-21 00:54:31 -08002930 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2931 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2932 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2933 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2934 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002935 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002938 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2939 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002940 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002941 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002942 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002943 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002944 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2945 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2946 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2947 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2948 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002949 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002950 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2951 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2952 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002953 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002954}
2955
wu@webrtc.orgde305012013-10-31 15:40:38 +00002956// This test verifies DSCP settings are properly applied on voice media channel.
2957TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002958 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002959 cricket::FakeNetworkInterface network_interface;
2960 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002961 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002962
peahb1c9d1d2017-07-25 15:45:24 -07002963 webrtc::AudioProcessing::Config apm_config;
2964 EXPECT_CALL(*apm_, GetConfig())
2965 .Times(3)
2966 .WillRepeatedly(ReturnPointee(&apm_config));
2967 EXPECT_CALL(*apm_, ApplyConfig(_))
2968 .Times(3)
2969 .WillRepeatedly(SaveArg<0>(&apm_config));
peaha9cc40b2017-06-29 08:32:09 -07002970 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002971
solenbergbc37fc82016-04-04 09:54:44 -07002972 channel.reset(
2973 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002974 channel->SetInterface(&network_interface);
2975 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2976 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2977
2978 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002979 channel.reset(
2980 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002981 channel->SetInterface(&network_interface);
2982 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2983
2984 // Verify that setting the option to false resets the
2985 // DiffServCodePoint.
2986 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002987 channel.reset(
2988 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002989 channel->SetInterface(&network_interface);
2990 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2991 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2992
2993 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002994}
2995
solenberg1ac56142015-10-13 03:58:19 -07002996TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002997 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 cricket::WebRtcVoiceMediaChannel* media_channel =
2999 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003000 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003001 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003002 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003003 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3004 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3005 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003006 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003007 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008}
3009
solenberg1ac56142015-10-13 03:58:19 -07003010TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003011 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003013 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3014 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3015 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003016 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003017 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003018 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3019 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003020 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003021 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003022 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003023 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024}
3025
solenberg4bac9c52015-10-09 02:32:53 -07003026TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003027 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003028 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003030 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003032 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3033 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3034 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003035}
3036
solenberg2100c0b2017-03-01 11:29:29 -08003037TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003038 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003039
3040 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003041 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003042 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3043
3044 // Should remember the volume "2" which will be set on new unsignaled streams,
3045 // and also set the gain to 2 on existing unsignaled streams.
3046 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3047 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3048
3049 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3050 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3051 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3052 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3053 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3054 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3055
3056 // Setting gain with SSRC=0 should affect all unsignaled streams.
3057 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003058 if (kMaxUnsignaledRecvStreams > 1) {
3059 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3060 }
solenberg2100c0b2017-03-01 11:29:29 -08003061 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3062
3063 // Setting gain on an individual stream affects only that.
3064 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003065 if (kMaxUnsignaledRecvStreams > 1) {
3066 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3067 }
solenberg2100c0b2017-03-01 11:29:29 -08003068 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069}
3070
pbos8fc7fa72015-07-15 08:02:58 -07003071TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003072 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003073 const std::string kSyncLabel = "AvSyncLabel";
3074
solenbergff976312016-03-30 23:28:51 -07003075 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003076 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3077 sp.sync_label = kSyncLabel;
3078 // Creating two channels to make sure that sync label is set properly for both
3079 // the default voice channel and following ones.
3080 EXPECT_TRUE(channel_->AddRecvStream(sp));
3081 sp.ssrcs[0] += 1;
3082 EXPECT_TRUE(channel_->AddRecvStream(sp));
3083
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003084 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003085 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003086 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003087 << "SyncGroup should be set based on sync_label";
3088 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003089 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003090 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003091}
3092
solenberg3a941542015-11-16 07:34:50 -08003093// TODO(solenberg): Remove, once recv streams are configured through Call.
3094// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003095TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003096 // Test that setting the header extensions results in the expected state
3097 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003098 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003099 ssrcs.push_back(223);
3100 ssrcs.push_back(224);
3101
solenbergff976312016-03-30 23:28:51 -07003102 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003103 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003104 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003105 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003106 cricket::StreamParams::CreateLegacy(ssrc)));
3107 }
3108
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003109 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003110 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003111 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 EXPECT_NE(nullptr, s);
3113 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3114 }
3115
3116 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003117 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003118 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003119 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003120 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003121 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003122 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003123 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003124 EXPECT_NE(nullptr, s);
3125 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003126 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3127 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003128 for (const auto& s_ext : s_exts) {
3129 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003130 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003131 }
3132 }
3133 }
3134 }
3135
3136 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003137 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003138 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003139 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003140 EXPECT_NE(nullptr, s);
3141 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3142 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003143}
3144
3145TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3146 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003147 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003148 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003149 static const unsigned char kRtcp[] = {
3150 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3151 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3154 };
jbaucheec21bd2016-03-20 06:15:43 -07003155 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003156
solenbergff976312016-03-30 23:28:51 -07003157 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003158 cricket::WebRtcVoiceMediaChannel* media_channel =
3159 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003160 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003161 EXPECT_TRUE(media_channel->AddRecvStream(
3162 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3163
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003164 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003165 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003166 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003167 EXPECT_EQ(0, s->received_packets());
3168 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3169 EXPECT_EQ(1, s->received_packets());
3170 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3171 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003172}
Minyue2013aec2015-05-13 14:14:42 +02003173
solenberg0a617e22015-10-20 15:49:38 -07003174// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003175// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003176TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003177 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003178 EXPECT_TRUE(AddRecvStream(kSsrcY));
3179 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003180 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003181 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3182 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3183 EXPECT_TRUE(AddRecvStream(kSsrcW));
3184 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003185}
3186
solenberg7602aab2016-11-14 11:30:07 -08003187TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3188 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003189 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003190 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003191 cricket::StreamParams::CreateLegacy(kSsrcY)));
3192 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3193 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3194 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003195 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003196 cricket::StreamParams::CreateLegacy(kSsrcW)));
3197 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3198 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003199}
stefan658910c2015-09-03 05:48:32 -07003200
deadbeef884f5852016-01-15 09:20:04 -08003201TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003202 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003203 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3204 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003205
3206 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003207 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3208 EXPECT_TRUE(AddRecvStream(kSsrcX));
3209 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003210
3211 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003212 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3213 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003214
3215 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003216 channel_->SetRawAudioSink(kSsrcX, nullptr);
3217 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003218}
3219
solenberg2100c0b2017-03-01 11:29:29 -08003220TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003221 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003222 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3223 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003224 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3225 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003226
3227 // Should be able to set a default sink even when no stream exists.
3228 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3229
solenberg2100c0b2017-03-01 11:29:29 -08003230 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3231 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003232 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003233 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003234
3235 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003236 channel_->SetRawAudioSink(kSsrc0, nullptr);
3237 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003238
3239 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003240 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3241 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003242
3243 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003244 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003245 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003246 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3247
3248 // Spawn another unsignaled stream - it should be assigned the default sink
3249 // and the previous unsignaled stream should lose it.
3250 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3251 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3252 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3253 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003254 if (kMaxUnsignaledRecvStreams > 1) {
3255 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3256 }
solenberg2100c0b2017-03-01 11:29:29 -08003257 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3258
3259 // Reset the default sink - the second unsignaled stream should lose it.
3260 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003261 if (kMaxUnsignaledRecvStreams > 1) {
3262 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3263 }
solenberg2100c0b2017-03-01 11:29:29 -08003264 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3265
3266 // Try setting the default sink while two streams exists.
3267 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003268 if (kMaxUnsignaledRecvStreams > 1) {
3269 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3270 }
solenberg2100c0b2017-03-01 11:29:29 -08003271 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3272
3273 // Try setting the sink for the first unsignaled stream using its known SSRC.
3274 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003275 if (kMaxUnsignaledRecvStreams > 1) {
3276 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3277 }
solenberg2100c0b2017-03-01 11:29:29 -08003278 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003279 if (kMaxUnsignaledRecvStreams > 1) {
3280 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3281 }
deadbeef884f5852016-01-15 09:20:04 -08003282}
3283
skvlad7a43d252016-03-22 15:32:27 -07003284// Test that, just like the video channel, the voice channel communicates the
3285// network state to the call.
3286TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003287 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003288
3289 EXPECT_EQ(webrtc::kNetworkUp,
3290 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3291 EXPECT_EQ(webrtc::kNetworkUp,
3292 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3293
3294 channel_->OnReadyToSend(false);
3295 EXPECT_EQ(webrtc::kNetworkDown,
3296 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3297 EXPECT_EQ(webrtc::kNetworkUp,
3298 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3299
3300 channel_->OnReadyToSend(true);
3301 EXPECT_EQ(webrtc::kNetworkUp,
3302 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3303 EXPECT_EQ(webrtc::kNetworkUp,
3304 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3305}
3306
aleloi18e0b672016-10-04 02:45:47 -07003307// Test that playout is still started after changing parameters
3308TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3309 SetupRecvStream();
3310 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003312
3313 // Changing RTP header extensions will recreate the AudioReceiveStream.
3314 cricket::AudioRecvParameters parameters;
3315 parameters.extensions.push_back(
3316 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3317 channel_->SetRecvParameters(parameters);
3318
solenberg2100c0b2017-03-01 11:29:29 -08003319 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003320}
3321
stefan658910c2015-09-03 05:48:32 -07003322// Tests that the library initializes and shuts down properly.
3323TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003324 // If the VoiceEngine wants to gather available codecs early, that's fine but
3325 // we never want it to create a decoder at this stage.
henrika919dc2e2017-10-12 14:24:55 +02003326 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003327 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3328 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003329 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003330 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003331 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003332 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003333 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003334 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003335 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003336 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3337 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003338 EXPECT_TRUE(channel != nullptr);
3339 delete channel;
solenbergff976312016-03-30 23:28:51 -07003340}
stefan658910c2015-09-03 05:48:32 -07003341
solenbergff976312016-03-30 23:28:51 -07003342// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003343TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3344 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
Niels Möller6f72f562017-10-19 13:15:17 +02003345 EXPECT_CALL(adm, AddRef()).Times(3);
3346 EXPECT_CALL(adm, Release())
3347 .Times(3)
3348 .WillRepeatedly(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
solenbergff976312016-03-30 23:28:51 -07003349 {
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(
ossueb1fde42017-05-02 06:46:30 -07003353 &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();
skvlad11a9cbf2016-10-07 11:53:05 -07003356 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003357 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003358 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003359 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3360 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3361 EXPECT_TRUE(channel != nullptr);
3362 delete channel;
3363 }
stefan658910c2015-09-03 05:48:32 -07003364}
3365
ossu20a4b3f2017-04-27 02:08:52 -07003366// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3367TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003368 // TODO(ossu): Why are the payload types of codecs with non-static payload
3369 // type assignments checked here? It shouldn't really matter.
henrika919dc2e2017-10-12 14:24:55 +02003370 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003371 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3372 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003373 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003374 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003375 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003376 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003377 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003378 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3379 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3380 (clockrate == 0 || codec.clockrate == clockrate);
3381 };
3382 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003383 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003384 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003385 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003386 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003387 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003388 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003389 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003390 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003391 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003392 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003393 EXPECT_EQ(126, codec.id);
3394 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3395 // Remove these checks once both send and receive side assigns payload types
3396 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003397 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003398 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003399 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003400 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003401 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003402 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003403 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003404 EXPECT_EQ(111, codec.id);
3405 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3406 EXPECT_EQ("10", codec.params.find("minptime")->second);
3407 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3408 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003409 }
3410 }
stefan658910c2015-09-03 05:48:32 -07003411}
3412
3413// Tests that VoE supports at least 32 channels
3414TEST(WebRtcVoiceEngineTest, Has32Channels) {
henrika919dc2e2017-10-12 14:24:55 +02003415 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003416 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3417 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003418 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003419 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003420 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003421 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003422 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003423 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003424 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003425
3426 cricket::VoiceMediaChannel* channels[32];
3427 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003428 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003429 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3430 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003431 if (!channel)
3432 break;
stefan658910c2015-09-03 05:48:32 -07003433 channels[num_channels++] = channel;
3434 }
3435
tfarina5237aaf2015-11-10 23:44:30 -08003436 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003437 EXPECT_EQ(expected, num_channels);
3438
3439 while (num_channels > 0) {
3440 delete channels[--num_channels];
3441 }
stefan658910c2015-09-03 05:48:32 -07003442}
3443
3444// Test that we set our preferred codecs properly.
3445TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003446 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3447 // - Check that our builtin codecs are usable by Channel.
3448 // - The codecs provided by the engine is usable by Channel.
3449 // It does not check that the codecs in the RecvParameters are actually
3450 // what we sent in - though it's probably reasonable to expect so, if
3451 // SetRecvParameters returns true.
3452 // I think it will become clear once audio decoder injection is completed.
henrika919dc2e2017-10-12 14:24:55 +02003453 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
peaha9cc40b2017-06-29 08:32:09 -07003454 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3455 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003456 cricket::WebRtcVoiceEngine engine(
henrika919dc2e2017-10-12 14:24:55 +02003457 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003458 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003459 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003460 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003461 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003462 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003463 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3464 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003465 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003466 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003467 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003468}
ossu9def8002017-02-09 05:14:32 -08003469
3470TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3471 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003472 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3473 {48000, 2, 16000, 10000, 20000}};
3474 spec1.info.allow_comfort_noise = false;
3475 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003476 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003477 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3478 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003479 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003480 specs.push_back(webrtc::AudioCodecSpec{
3481 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3482 {16000, 1, 13300}});
3483 specs.push_back(
3484 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3485 specs.push_back(
3486 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003487
ossueb1fde42017-05-02 06:46:30 -07003488 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3489 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3490 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003491 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003492 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003493 .WillOnce(Return(specs));
henrika919dc2e2017-10-12 14:24:55 +02003494 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
ossu9def8002017-02-09 05:14:32 -08003495
peaha9cc40b2017-06-29 08:32:09 -07003496 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3497 webrtc::AudioProcessing::Create();
henrika919dc2e2017-10-12 14:24:55 +02003498 cricket::WebRtcVoiceEngine engine(&adm, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003499 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003500 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003501 auto codecs = engine.recv_codecs();
3502 EXPECT_EQ(11, codecs.size());
3503
3504 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3505 // check the actual values safely, to provide better test results.
3506 auto get_codec =
3507 [&codecs](size_t index) -> const cricket::AudioCodec& {
3508 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3509 if (codecs.size() > index)
3510 return codecs[index];
3511 return missing_codec;
3512 };
3513
3514 // Ensure the general codecs are generated first and in order.
3515 for (size_t i = 0; i != specs.size(); ++i) {
3516 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3517 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3518 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3519 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3520 }
3521
3522 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003523 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003524 auto find_codec =
3525 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3526 for (size_t i = 0; i != codecs.size(); ++i) {
3527 const cricket::AudioCodec& codec = codecs[i];
3528 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3529 codec.clockrate == format.clockrate_hz &&
3530 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003531 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003532 }
3533 }
3534 return -1;
3535 };
3536
3537 // Ensure all supplementary codecs are generated last. Their internal ordering
3538 // is not important.
3539 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3540 const int num_specs = static_cast<int>(specs.size());
3541 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3542 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3543 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3544 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3545 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3546 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3547 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3548}