blob: dfb49cf87be383624f4c3dd2d69ceedcc0acca00 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080014#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000015#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080016#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070018#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakemediaengine.h"
20#include "webrtc/media/base/fakenetworkinterface.h"
21#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080022#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010023#include "webrtc/media/engine/fakewebrtccall.h"
24#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
25#include "webrtc/media/engine/webrtcvoiceengine.h"
solenbergbc37fc82016-04-04 09:54:44 -070026#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070027#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080028#include "webrtc/pc/channel.h"
29#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080030#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070031#include "webrtc/test/mock_audio_decoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080032#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
kwiberg1c07c702017-03-27 07:15:49 -070034using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070035using testing::Return;
36using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000037
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020038namespace {
39
solenbergebb349d2017-03-13 05:46:15 -070040constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
41
deadbeef67cf2c12016-04-13 10:07:16 -070042const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
43const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
44const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
45const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
46const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070047const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
48const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080049const cricket::AudioCodec
50 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
51const cricket::AudioCodec
52 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
53
solenberg2100c0b2017-03-01 11:29:29 -080054const uint32_t kSsrc0 = 0;
55const uint32_t kSsrc1 = 1;
56const uint32_t kSsrcX = 0x99;
57const uint32_t kSsrcY = 0x17;
58const uint32_t kSsrcZ = 0x42;
59const uint32_t kSsrcW = 0x02;
60const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
solenberg971cab02016-06-14 10:02:41 -070062constexpr int kRtpHistoryMs = 5000;
63
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064class FakeVoEWrapper : public cricket::VoEWrapper {
65 public:
66 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070067 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 }
69};
skvlad11a9cbf2016-10-07 11:53:05 -070070
solenberg76377c52017-02-21 00:54:31 -080071class MockTransmitMixer : public webrtc::voe::TransmitMixer {
72 public:
73 MockTransmitMixer() = default;
74 virtual ~MockTransmitMixer() = default;
75
76 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
77};
solenberg9a5f032222017-03-15 06:14:12 -070078
79void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
80 RTC_DCHECK(adm);
81 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
82 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
83#if !defined(WEBRTC_IOS)
84 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
85 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
86 ChannelType::kChannelBoth)).WillOnce(Return(0));
87#if defined(WEBRTC_WIN)
88 EXPECT_CALL(*adm, SetRecordingDevice(
89 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
90 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
91 .WillOnce(Return(0));
92#else
93 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
94#endif // #if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
96 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
97 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
98 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
99#if defined(WEBRTC_WIN)
100 EXPECT_CALL(*adm, SetPlayoutDevice(
101 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
102 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
103 .WillOnce(Return(0));
104#else
105 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
106#endif // #if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
108 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
109 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
110#endif // #if !defined(WEBRTC_IOS)
111 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
115}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200116} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117
solenbergff976312016-03-30 23:28:51 -0700118// Tests that our stub library "works".
119TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700120 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700121 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700122 StrictMock<webrtc::test::MockAudioProcessing> apm;
123 EXPECT_CALL(apm, ApplyConfig(testing::_));
124 EXPECT_CALL(apm, SetExtraOptions(testing::_));
125 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800126 StrictMock<MockTransmitMixer> transmit_mixer;
127 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
128 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700129 EXPECT_FALSE(voe.IsInited());
130 {
ossuc54071d2016-08-17 02:45:41 -0700131 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -0800132 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700133 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700134 EXPECT_TRUE(voe.IsInited());
135 }
136 EXPECT_FALSE(voe.IsInited());
137}
138
deadbeef884f5852016-01-15 09:20:04 -0800139class FakeAudioSink : public webrtc::AudioSinkInterface {
140 public:
141 void OnData(const Data& audio) override {}
142};
143
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800144class FakeAudioSource : public cricket::AudioSource {
145 void SetSink(Sink* sink) override {}
146};
147
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148class WebRtcVoiceEngineTestFake : public testing::Test {
149 public:
stefanba4c0e42016-02-04 04:12:24 -0800150 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
151
152 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800153 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
154 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
155 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700156 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800157 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700158 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800159 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700160 EXPECT_CALL(apm_, ApplyConfig(testing::_));
161 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
162 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800163 // Default Options.
164 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
165 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
166 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
167 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
168 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
169 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
170 // Init does not overwrite default AGC config.
171 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
172 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
173 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
174 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
175 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
176 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800177 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
178 // the tests here probe the specific set of codecs provided by the builtin
179 // factory. Those tests should probably be moved elsewhere.
180 engine_.reset(new cricket::WebRtcVoiceEngine(
181 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
182 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200183 send_parameters_.codecs.push_back(kPcmuCodec);
184 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800185 // Default Options.
186 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 }
solenberg8189b022016-06-14 12:13:00 -0700188
solenbergff976312016-03-30 23:28:51 -0700189 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700190 EXPECT_CALL(apm_, ApplyConfig(testing::_));
191 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700192 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
193 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200194 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000195 }
solenberg8189b022016-06-14 12:13:00 -0700196
solenbergff976312016-03-30 23:28:51 -0700197 bool SetupRecvStream() {
198 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700199 return false;
200 }
solenberg2100c0b2017-03-01 11:29:29 -0800201 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700202 }
solenberg8189b022016-06-14 12:13:00 -0700203
solenbergff976312016-03-30 23:28:51 -0700204 bool SetupSendStream() {
205 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000206 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 }
solenberg2100c0b2017-03-01 11:29:29 -0800208 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800209 return false;
210 }
solenberg059fb442016-10-26 05:12:24 -0700211 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800212 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 }
solenberg8189b022016-06-14 12:13:00 -0700214
215 bool AddRecvStream(uint32_t ssrc) {
216 EXPECT_TRUE(channel_);
217 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
218 }
219
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000220 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700221 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700222 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800223 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
224 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700225 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800226 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000227 }
solenberg8189b022016-06-14 12:13:00 -0700228
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700230 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000231 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200234 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
237
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100238 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
239 const auto* send_stream = call_.GetAudioSendStream(ssrc);
240 EXPECT_TRUE(send_stream);
241 return *send_stream;
242 }
243
deadbeef884f5852016-01-15 09:20:04 -0800244 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
245 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
246 EXPECT_TRUE(recv_stream);
247 return *recv_stream;
248 }
249
solenberg3a941542015-11-16 07:34:50 -0800250 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800251 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800252 }
253
solenberg7add0582015-11-20 09:59:34 -0800254 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800255 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800256 }
257
solenberg059fb442016-10-26 05:12:24 -0700258 void SetSend(bool enable) {
259 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700260 if (enable) {
261 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
262 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
263 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700264 EXPECT_CALL(apm_, ApplyConfig(testing::_));
265 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700266 }
solenberg059fb442016-10-26 05:12:24 -0700267 channel_->SetSend(enable);
268 }
269
270 void SetSendParameters(const cricket::AudioSendParameters& params) {
271 EXPECT_CALL(apm_, ApplyConfig(testing::_));
272 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
273 ASSERT_TRUE(channel_);
274 EXPECT_TRUE(channel_->SetSendParameters(params));
275 }
276
minyue6b825df2016-10-31 04:08:32 -0700277 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
278 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700279 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
280 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700281 if (enable && options) {
282 EXPECT_CALL(apm_, ApplyConfig(testing::_));
283 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
284 }
285 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700286 }
287
solenbergffbbcac2016-11-17 05:25:37 -0800288 void TestInsertDtmf(uint32_t ssrc, bool caller,
289 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700290 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000291 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700292 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000293 // send stream.
294 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800295 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000296 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000297
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700299 SetSendParameters(send_parameters_);
300 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800302 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800303 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700304 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306
307 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700308 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800309 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800311 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 }
313
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800315 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100317 // Test send.
318 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800319 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100320 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800322 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800323 EXPECT_EQ(codec.id, telephone_event.payload_type);
324 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100325 EXPECT_EQ(2, telephone_event.event_code);
326 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 }
328
329 // Test that send bandwidth is set correctly.
330 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000331 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
332 // |expected_result| is the expected result from SetMaxSendBandwidth().
333 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700334 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
335 int max_bitrate,
336 bool expected_result,
337 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200338 cricket::AudioSendParameters parameters;
339 parameters.codecs.push_back(codec);
340 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700341 if (expected_result) {
342 SetSendParameters(parameters);
343 } else {
344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
345 }
solenberg2100c0b2017-03-01 11:29:29 -0800346 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 }
348
skvlade0d46372016-04-07 22:59:22 -0700349 // Sets the per-stream maximum bitrate limit for the specified SSRC.
350 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700351 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700352 EXPECT_EQ(1UL, parameters.encodings.size());
353
deadbeefe702b302017-02-04 12:09:01 -0800354 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700355 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700356 }
357
solenberg059fb442016-10-26 05:12:24 -0700358 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700359 cricket::AudioSendParameters send_parameters;
360 send_parameters.codecs.push_back(codec);
361 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700362 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700363 }
364
minyue7a973442016-10-20 03:27:12 -0700365 void CheckSendCodec(int32_t ssrc,
366 const char expected_name[],
367 int expected_channels,
368 int expected_bitrate) {
369 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
370 EXPECT_STREQ(expected_name, codec.plname);
371 EXPECT_EQ(expected_channels, codec.channels);
372 EXPECT_EQ(expected_bitrate, codec.rate);
373 }
374
375 int GetOpusMaxPlaybackRate(int32_t ssrc) {
376 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
377 }
378
379 bool GetOpusDtx(int32_t ssrc) {
380 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
381 }
382
383 bool GetCodecFec(int32_t ssrc) {
384 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
385 }
386
skvlade0d46372016-04-07 22:59:22 -0700387 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700388 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
389 }
390
391 int GetCodecPacSize(int32_t ssrc) {
392 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
minyue6b825df2016-10-31 04:08:32 -0700395 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
396 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
397 }
398
skvlade0d46372016-04-07 22:59:22 -0700399 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
400 int global_max,
401 int stream_max,
402 bool expected_result,
403 int expected_codec_bitrate) {
404 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800405 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700406
407 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700408 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800409 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700410
411 // Verify that reading back the parameters gives results
412 // consistent with the Set() result.
413 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800414 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700415 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
416 EXPECT_EQ(expected_result ? stream_max : -1,
417 resulting_parameters.encodings[0].max_bitrate_bps);
418
419 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800420 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700421 }
422
stefan13f1a0a2016-11-30 07:22:58 -0800423 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
424 int expected_min_bitrate_bps,
425 const char* start_bitrate_kbps,
426 int expected_start_bitrate_bps,
427 const char* max_bitrate_kbps,
428 int expected_max_bitrate_bps) {
429 EXPECT_TRUE(SetupSendStream());
430 auto& codecs = send_parameters_.codecs;
431 codecs.clear();
432 codecs.push_back(kOpusCodec);
433 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
436 SetSendParameters(send_parameters_);
437
438 EXPECT_EQ(expected_min_bitrate_bps,
439 call_.GetConfig().bitrate_config.min_bitrate_bps);
440 EXPECT_EQ(expected_start_bitrate_bps,
441 call_.GetConfig().bitrate_config.start_bitrate_bps);
442 EXPECT_EQ(expected_max_bitrate_bps,
443 call_.GetConfig().bitrate_config.max_bitrate_bps);
444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800536 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
541 stats.aec_quality_min = 9.01f;
542 stats.echo_delay_median_ms = 234;
543 stats.echo_delay_std_ms = 567;
544 stats.echo_return_loss = 890;
545 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700546 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800547 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700548 stats.typing_noise_detected = true;
549 return stats;
550 }
551 void SetAudioSendStreamStats() {
552 for (auto* s : call_.GetAudioSendStreams()) {
553 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200554 }
solenberg85a04962015-10-27 03:35:21 -0700555 }
solenberg566ef242015-11-06 15:34:49 -0800556 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
557 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700558 const auto stats = GetAudioSendStreamStats();
559 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
560 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
561 EXPECT_EQ(info.packets_sent, stats.packets_sent);
562 EXPECT_EQ(info.packets_lost, stats.packets_lost);
563 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
564 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800565 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700566 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
567 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
568 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
569 EXPECT_EQ(info.audio_level, stats.audio_level);
570 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
571 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
572 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
573 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
574 EXPECT_EQ(info.echo_return_loss_enhancement,
575 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700576 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800577 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
578 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800579 EXPECT_EQ(info.typing_noise_detected,
580 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700581 }
582
583 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
584 webrtc::AudioReceiveStream::Stats stats;
585 stats.remote_ssrc = 123;
586 stats.bytes_rcvd = 456;
587 stats.packets_rcvd = 768;
588 stats.packets_lost = 101;
589 stats.fraction_lost = 23.45f;
590 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800591 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700592 stats.ext_seqnum = 678;
593 stats.jitter_ms = 901;
594 stats.jitter_buffer_ms = 234;
595 stats.jitter_buffer_preferred_ms = 567;
596 stats.delay_estimate_ms = 890;
597 stats.audio_level = 1234;
598 stats.expand_rate = 5.67f;
599 stats.speech_expand_rate = 8.90f;
600 stats.secondary_decoded_rate = 1.23f;
601 stats.accelerate_rate = 4.56f;
602 stats.preemptive_expand_rate = 7.89f;
603 stats.decoding_calls_to_silence_generator = 12;
604 stats.decoding_calls_to_neteq = 345;
605 stats.decoding_normal = 67890;
606 stats.decoding_plc = 1234;
607 stats.decoding_cng = 5678;
608 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700609 stats.decoding_muted_output = 3456;
610 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200611 return stats;
612 }
613 void SetAudioReceiveStreamStats() {
614 for (auto* s : call_.GetAudioReceiveStreams()) {
615 s->SetStats(GetAudioReceiveStreamStats());
616 }
617 }
618 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700619 const auto stats = GetAudioReceiveStreamStats();
620 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
621 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
622 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
623 EXPECT_EQ(info.packets_lost, stats.packets_lost);
624 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
625 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800626 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700627 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
628 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
629 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200630 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700631 stats.jitter_buffer_preferred_ms);
632 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
633 EXPECT_EQ(info.audio_level, stats.audio_level);
634 EXPECT_EQ(info.expand_rate, stats.expand_rate);
635 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
636 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
637 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
638 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700640 stats.decoding_calls_to_silence_generator);
641 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
642 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
643 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
644 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
645 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700646 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200648 }
hbos1acfbd22016-11-17 23:43:29 -0800649 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
650 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
651 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
652 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
653 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
654 codec.ToCodecParameters());
655 }
656 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
657 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
658 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
659 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
660 codec.ToCodecParameters());
661 }
662 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200663
peah8271d042016-11-22 07:24:52 -0800664 bool IsHighPassFilterEnabled() {
665 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
666 }
667
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700669 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700670 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800671 webrtc::test::MockGainControl& apm_gc_;
672 webrtc::test::MockEchoCancellation& apm_ec_;
673 webrtc::test::MockNoiseSuppression& apm_ns_;
674 webrtc::test::MockVoiceDetection& apm_vd_;
675 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700676 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200677 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700679 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700680 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200681 cricket::AudioSendParameters send_parameters_;
682 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800683 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800684 private:
685 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686};
687
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688// Tests that we can create and destroy a channel.
689TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700690 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691}
692
solenberg31fec402016-05-06 02:13:12 -0700693// Test that we can add a send stream and that it has the correct defaults.
694TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
695 EXPECT_TRUE(SetupChannel());
696 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800697 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
698 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
699 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700700 EXPECT_EQ("", config.rtp.c_name);
701 EXPECT_EQ(0u, config.rtp.extensions.size());
702 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
703 config.send_transport);
704}
705
706// Test that we can add a receive stream and that it has the correct defaults.
707TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
708 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800709 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700710 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800711 GetRecvStreamConfig(kSsrcX);
712 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700713 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
714 EXPECT_FALSE(config.rtp.transport_cc);
715 EXPECT_EQ(0u, config.rtp.extensions.size());
716 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
717 config.rtcp_send_transport);
718 EXPECT_EQ("", config.sync_group);
719}
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700722// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700723// TODO(ossu): This test should move into a separate builtin audio codecs
724// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700725TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700726 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 ASSERT_FALSE(codecs.empty());
728 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
729 EXPECT_EQ(48000, codecs[0].clockrate);
730 EXPECT_EQ(2, codecs[0].channels);
731 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732}
733
stefanba4c0e42016-02-04 04:12:24 -0800734TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700735 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800736 bool opus_found = false;
737 for (cricket::AudioCodec codec : codecs) {
738 if (codec.name == "opus") {
739 EXPECT_TRUE(HasTransportCc(codec));
740 opus_found = true;
741 }
742 }
743 EXPECT_TRUE(opus_found);
744}
745
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746// Tests that we can find codecs by name or id, and that we interpret the
747// clockrate and bitrate fields properly.
748TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
749 cricket::AudioCodec codec;
750 webrtc::CodecInst codec_inst;
751 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800752 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000753 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800754 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800756 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
757 &codec_inst));
758 // Find telephone-event with explicit clockrate and 0 bitrate.
759 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800760 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 // Find ISAC with a different payload id.
762 codec = kIsacCodec;
763 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800764 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 EXPECT_EQ(codec.id, codec_inst.pltype);
766 // Find PCMU with a 0 clockrate.
767 codec = kPcmuCodec;
768 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800769 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 EXPECT_EQ(codec.id, codec_inst.pltype);
771 EXPECT_EQ(8000, codec_inst.plfreq);
772 // Find PCMU with a 0 bitrate.
773 codec = kPcmuCodec;
774 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800775 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 EXPECT_EQ(codec.id, codec_inst.pltype);
777 EXPECT_EQ(64000, codec_inst.rate);
778 // Find ISAC with an explicit bitrate.
779 codec = kIsacCodec;
780 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800781 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 EXPECT_EQ(codec.id, codec_inst.pltype);
783 EXPECT_EQ(32000, codec_inst.rate);
784}
785
786// Test that we set our inbound codecs properly, including changing PT.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
791 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800792 parameters.codecs.push_back(kTelephoneEventCodec1);
793 parameters.codecs.push_back(kTelephoneEventCodec2);
794 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 parameters.codecs[2].id = 126;
796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700798 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
799 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
800 {{0, {"PCMU", 8000, 1}},
801 {106, {"ISAC", 16000, 1}},
802 {126, {"telephone-event", 8000, 1}},
803 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that we fail to set an unknown inbound codec.
807TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700808 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200809 cricket::AudioRecvParameters parameters;
810 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700811 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813}
814
815// Test that we fail if we have duplicate types in the inbound list.
816TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 cricket::AudioRecvParameters parameters;
819 parameters.codecs.push_back(kIsacCodec);
820 parameters.codecs.push_back(kCn16000Codec);
821 parameters.codecs[1].id = kIsacCodec.id;
822 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that we can decode OPUS without stereo parameters.
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
830 parameters.codecs.push_back(kPcmuCodec);
831 parameters.codecs.push_back(kOpusCodec);
832 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800833 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700834 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
835 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
836 {{0, {"PCMU", 8000, 1}},
837 {103, {"ISAC", 16000, 1}},
838 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that we can decode OPUS with stereo = 0.
842TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 cricket::AudioRecvParameters parameters;
845 parameters.codecs.push_back(kIsacCodec);
846 parameters.codecs.push_back(kPcmuCodec);
847 parameters.codecs.push_back(kOpusCodec);
848 parameters.codecs[2].params["stereo"] = "0";
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800850 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700851 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
852 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
853 {{0, {"PCMU", 8000, 1}},
854 {103, {"ISAC", 16000, 1}},
855 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we can decode OPUS with stereo = 1.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kPcmuCodec);
864 parameters.codecs.push_back(kOpusCodec);
865 parameters.codecs[2].params["stereo"] = "1";
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800867 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700868 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {103, {"ISAC", 16000, 1}},
872 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000873}
874
875// Test that changes to recv codecs are applied to all streams.
876TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700877 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs.push_back(kTelephoneEventCodec1);
882 parameters.codecs.push_back(kTelephoneEventCodec2);
883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 parameters.codecs[2].id = 126;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700886 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
887 EXPECT_TRUE(AddRecvStream(ssrc));
888 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
889 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
890 {{0, {"PCMU", 8000, 1}},
891 {106, {"ISAC", 16000, 1}},
892 {126, {"telephone-event", 8000, 1}},
893 {107, {"telephone-event", 32000, 1}}})));
894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895}
896
897TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
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);
solenberg2779bab2016-11-17 04:45:19 -0800901 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
solenberg2100c0b2017-03-01 11:29:29 -0800904 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800905 ASSERT_EQ(1, dm.count(106));
906 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907}
908
909// Test that we can apply the same set of codecs again while playing.
910TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700911 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 cricket::AudioRecvParameters parameters;
913 parameters.codecs.push_back(kIsacCodec);
914 parameters.codecs.push_back(kCn16000Codec);
915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700916 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
deadbeefcb383672017-04-26 16:28:42 -0700919 // Remapping a payload type to a different codec should fail.
920 parameters.codecs[0] = kOpusCodec;
921 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800923 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924}
925
926// Test that we can add a codec while playing.
927TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700928 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200929 cricket::AudioRecvParameters parameters;
930 parameters.codecs.push_back(kIsacCodec);
931 parameters.codecs.push_back(kCn16000Codec);
932 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700933 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200935 parameters.codecs.push_back(kOpusCodec);
936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800937 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800939 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
941}
942
deadbeefcb383672017-04-26 16:28:42 -0700943// Test that we accept adding the same codec with a different payload type.
944// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
945TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
946 EXPECT_TRUE(SetupRecvStream());
947 cricket::AudioRecvParameters parameters;
948 parameters.codecs.push_back(kIsacCodec);
949 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
950
951 ++parameters.codecs[0].id;
952 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
953}
954
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700956 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000958 // Test that when autobw is enabled, bitrate is kept as the default
959 // value. autobw is enabled for the following tests because the target
960 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
962 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700963 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964
965 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700966 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000967
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700969 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970}
971
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000972TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700973 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000975 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
977 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700978 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
979 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
980 // Rates above the max (56000) should be capped.
981 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700984 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
985 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
986 // Rates above the max (510000) should be capped.
987 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988}
989
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000990TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700991 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000992
993 // Test that we can only set a maximum bitrate for a fixed-rate codec
994 // if it's bigger than the fixed rate.
995
996 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700997 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
998 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1000 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1001 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1002 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1003 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001004}
1005
1006TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001007 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001008 const int kDesiredBitrate = 128000;
1009 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001010 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001011 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001012 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001013
1014 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001015 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001016
solenberg2100c0b2017-03-01 11:29:29 -08001017 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001018}
1019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020// Test that bitrate cannot be set for CBR codecs.
1021// Bitrate is ignored if it is higher than the fixed bitrate.
1022// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001023TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001024 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025
1026 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001027 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001028 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029
1030 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001031 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001032 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001033
1034 send_parameters_.max_bandwidth_bps = 128;
1035 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001036 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001037}
1038
skvlade0d46372016-04-07 22:59:22 -07001039// Test that the per-stream bitrate limit and the global
1040// bitrate limit both apply.
1041TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1042 EXPECT_TRUE(SetupSendStream());
1043
1044 // opus, default bitrate == 64000.
1045 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1046 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1047 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1048 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1049
1050 // CBR codecs allow both maximums to exceed the bitrate.
1051 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1052 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1053 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1054 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1055
1056 // CBR codecs don't allow per stream maximums to be too low.
1057 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1058 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1059}
1060
1061// Test that an attempt to set RtpParameters for a stream that does not exist
1062// fails.
1063TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1064 EXPECT_TRUE(SetupChannel());
1065 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001066 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001067 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1068
1069 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001070 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001071}
1072
1073TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001074 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001075 // This test verifies that setting RtpParameters succeeds only if
1076 // the structure contains exactly one encoding.
1077 // TODO(skvlad): Update this test when we start supporting setting parameters
1078 // for each encoding individually.
1079
1080 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001081 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001082 // Two or more encodings should result in failure.
1083 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001084 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001085 // Zero encodings should also fail.
1086 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001087 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001088}
1089
1090// Changing the SSRC through RtpParameters is not allowed.
1091TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1092 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001093 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001094 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001095 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001096}
1097
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001099// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001100TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1101 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001102 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001104 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001105 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001106 ASSERT_EQ(1u, parameters.encodings.size());
1107 ASSERT_TRUE(parameters.encodings[0].active);
1108 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001109 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1110 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001111
1112 // Now change it back to active and verify we resume sending.
1113 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001114 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1115 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001116}
1117
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001118// Test that SetRtpSendParameters configures the correct encoding channel for
1119// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001120TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1121 SetupForMultiSendStream();
1122 // Create send streams.
1123 for (uint32_t ssrc : kSsrcs4) {
1124 EXPECT_TRUE(
1125 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1126 }
1127 // Configure one stream to be limited by the stream config, another to be
1128 // limited by the global max, and the third one with no per-stream limit
1129 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001130 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001131 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1132 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1133 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1134
1135 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1136 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1137 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1138
1139 // Remove the global cap; the streams should switch to their respective
1140 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001141 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001142 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1143 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1144 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1145}
1146
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001147// Test that GetRtpSendParameters returns the currently configured codecs.
1148TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001149 EXPECT_TRUE(SetupSendStream());
1150 cricket::AudioSendParameters parameters;
1151 parameters.codecs.push_back(kIsacCodec);
1152 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001153 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001154
solenberg2100c0b2017-03-01 11:29:29 -08001155 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1158 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001159}
1160
deadbeefcb443432016-12-12 11:12:36 -08001161// Test that GetRtpSendParameters returns an SSRC.
1162TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1163 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001164 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001165 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001166 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001167}
1168
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001169// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001170TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001171 EXPECT_TRUE(SetupSendStream());
1172 cricket::AudioSendParameters parameters;
1173 parameters.codecs.push_back(kIsacCodec);
1174 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001175 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001176
solenberg2100c0b2017-03-01 11:29:29 -08001177 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001178
1179 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001180 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001181
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001182 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001183 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1184 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001185}
1186
minyuececec102017-03-27 13:04:25 -07001187// Test that max_bitrate_bps in send stream config gets updated correctly when
1188// SetRtpSendParameters is called.
1189TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1190 webrtc::test::ScopedFieldTrials override_field_trials(
1191 "WebRTC-Audio-SendSideBwe/Enabled/");
1192 EXPECT_TRUE(SetupSendStream());
1193 cricket::AudioSendParameters send_parameters;
1194 send_parameters.codecs.push_back(kOpusCodec);
1195 SetSendParameters(send_parameters);
1196
1197 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1198 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1199 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1200
1201 constexpr int kMaxBitrateBps = 6000;
1202 rtp_parameters.encodings[0].max_bitrate_bps =
1203 rtc::Optional<int>(kMaxBitrateBps);
1204 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1205
1206 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1207 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1208}
1209
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001210// Test that GetRtpReceiveParameters returns the currently configured codecs.
1211TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1212 EXPECT_TRUE(SetupRecvStream());
1213 cricket::AudioRecvParameters parameters;
1214 parameters.codecs.push_back(kIsacCodec);
1215 parameters.codecs.push_back(kPcmuCodec);
1216 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1217
1218 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001219 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001220 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1221 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1222 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1223}
1224
deadbeefcb443432016-12-12 11:12:36 -08001225// Test that GetRtpReceiveParameters returns an SSRC.
1226TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1227 EXPECT_TRUE(SetupRecvStream());
1228 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001229 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001230 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001231 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001232}
1233
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001234// Test that if we set/get parameters multiple times, we get the same results.
1235TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1236 EXPECT_TRUE(SetupRecvStream());
1237 cricket::AudioRecvParameters parameters;
1238 parameters.codecs.push_back(kIsacCodec);
1239 parameters.codecs.push_back(kPcmuCodec);
1240 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1241
1242 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001243 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001244
1245 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001246 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001247
1248 // ... And this shouldn't change the params returned by
1249 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001250 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1251 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001252}
1253
deadbeef3bc15102017-04-20 19:25:07 -07001254// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1255// aren't signaled. It should return an empty "RtpEncodingParameters" when
1256// configured to receive an unsignaled stream and no packets have been received
1257// yet, and start returning the SSRC once a packet has been received.
1258TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1259 ASSERT_TRUE(SetupChannel());
1260 // Call necessary methods to configure receiving a default stream as
1261 // soon as it arrives.
1262 cricket::AudioRecvParameters parameters;
1263 parameters.codecs.push_back(kIsacCodec);
1264 parameters.codecs.push_back(kPcmuCodec);
1265 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1266
1267 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1268 // stream. Should return nothing.
1269 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1270
1271 // Set a sink for an unsignaled stream.
1272 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1273 // Value of "0" means "unsignaled stream".
1274 channel_->SetRawAudioSink(0, std::move(fake_sink));
1275
1276 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1277 // in this method means "unsignaled stream".
1278 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1279 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1280 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1281
1282 // Receive PCMU packet (SSRC=1).
1283 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1284
1285 // The |ssrc| member should still be unset.
1286 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1287 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1288 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1289}
1290
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291// Test that we apply codecs properly.
1292TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001293 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kIsacCodec);
1296 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001297 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001298 parameters.codecs[0].id = 96;
1299 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001300 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001301 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001302 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001303 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001304 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1305 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1306 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1307 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001308 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001309 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001310}
1311
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001312// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1313// to apply.
1314TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
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(kIsacCodec);
1318 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001319 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001320 parameters.codecs[0].id = 96;
1321 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001322 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001323 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001324 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001325 // Calling SetSendCodec again with same codec which is already set.
1326 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001327 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001328 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001329}
1330
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001331// Verify that G722 is set with 16000 samples per second to WebRTC.
1332TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001333 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001334 cricket::AudioSendParameters parameters;
1335 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001336 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001337 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001338 EXPECT_STREQ("G722", gcodec.plname);
1339 EXPECT_EQ(1, gcodec.channels);
1340 EXPECT_EQ(16000, gcodec.plfreq);
1341}
1342
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001343// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001345 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 cricket::AudioSendParameters parameters;
1347 parameters.codecs.push_back(kOpusCodec);
1348 parameters.codecs[0].bitrate = 0;
1349 parameters.codecs[0].clockrate = 50000;
1350 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351}
1352
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001353// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001355 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001356 cricket::AudioSendParameters parameters;
1357 parameters.codecs.push_back(kOpusCodec);
1358 parameters.codecs[0].bitrate = 0;
1359 parameters.codecs[0].channels = 0;
1360 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001361}
1362
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001363// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001365 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001366 cricket::AudioSendParameters parameters;
1367 parameters.codecs.push_back(kOpusCodec);
1368 parameters.codecs[0].bitrate = 0;
1369 parameters.codecs[0].channels = 0;
1370 parameters.codecs[0].params["stereo"] = "1";
1371 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001372}
1373
1374// Test that if channel is 1 for opus and there's no stereo, we fail.
1375TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001376 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 cricket::AudioSendParameters parameters;
1378 parameters.codecs.push_back(kOpusCodec);
1379 parameters.codecs[0].bitrate = 0;
1380 parameters.codecs[0].channels = 1;
1381 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382}
1383
1384// Test that if channel is 1 for opus and stereo=0, we fail.
1385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001386 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 cricket::AudioSendParameters parameters;
1388 parameters.codecs.push_back(kOpusCodec);
1389 parameters.codecs[0].bitrate = 0;
1390 parameters.codecs[0].channels = 1;
1391 parameters.codecs[0].params["stereo"] = "0";
1392 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393}
1394
1395// Test that if channel is 1 for opus and stereo=1, we fail.
1396TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001397 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001398 cricket::AudioSendParameters parameters;
1399 parameters.codecs.push_back(kOpusCodec);
1400 parameters.codecs[0].bitrate = 0;
1401 parameters.codecs[0].channels = 1;
1402 parameters.codecs[0].params["stereo"] = "1";
1403 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404}
1405
1406// Test that with bitrate=0 and no stereo,
1407// channels and bitrate are 1 and 32000.
1408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001409 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 cricket::AudioSendParameters parameters;
1411 parameters.codecs.push_back(kOpusCodec);
1412 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001413 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001414 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415}
1416
1417// Test that with bitrate=0 and stereo=0,
1418// channels and bitrate are 1 and 32000.
1419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 0;
1424 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001426 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001427}
1428
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001429// Test that with bitrate=invalid and stereo=0,
1430// channels and bitrate are 1 and 32000.
1431TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001432 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001433 cricket::AudioSendParameters parameters;
1434 parameters.codecs.push_back(kOpusCodec);
1435 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001436 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001438 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001439 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001440
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001441 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001443 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001444}
1445
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001446// Test that with bitrate=0 and stereo=1,
1447// channels and bitrate are 2 and 64000.
1448TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001449 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::AudioSendParameters parameters;
1451 parameters.codecs.push_back(kOpusCodec);
1452 parameters.codecs[0].bitrate = 0;
1453 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001454 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001455 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456}
1457
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001458// Test that with bitrate=invalid and stereo=1,
1459// channels and bitrate are 2 and 64000.
1460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001461 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001462 cricket::AudioSendParameters parameters;
1463 parameters.codecs.push_back(kOpusCodec);
1464 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001465 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001467 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001468 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001469
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001471 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001472 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001473}
1474
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475// Test that with bitrate=N and stereo unset,
1476// channels and bitrate are 1 and N.
1477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
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 = 96000;
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001483 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484 EXPECT_EQ(111, gcodec.pltype);
1485 EXPECT_EQ(96000, gcodec.rate);
1486 EXPECT_STREQ("opus", gcodec.plname);
1487 EXPECT_EQ(1, gcodec.channels);
1488 EXPECT_EQ(48000, gcodec.plfreq);
1489}
1490
1491// Test that with bitrate=N and stereo=0,
1492// channels and bitrate are 1 and N.
1493TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001494 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 cricket::AudioSendParameters parameters;
1496 parameters.codecs.push_back(kOpusCodec);
1497 parameters.codecs[0].bitrate = 30000;
1498 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001499 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001500 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501}
1502
1503// Test that with bitrate=N and without any parameters,
1504// channels and bitrate are 1 and N.
1505TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001506 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001507 cricket::AudioSendParameters parameters;
1508 parameters.codecs.push_back(kOpusCodec);
1509 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001510 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001511 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512}
1513
1514// Test that with bitrate=N and stereo=1,
1515// channels and bitrate are 2 and N.
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001517 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].bitrate = 30000;
1521 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001522 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001523 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524}
1525
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001526// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1527// Also test that the "maxaveragebitrate" can't be set to values outside the
1528// range of 6000 and 510000
1529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001530 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 cricket::AudioSendParameters parameters;
1532 parameters.codecs.push_back(kOpusCodec);
1533 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001534 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001536 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001537 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001538
1539 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001541 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001543
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001544 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001545 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001546 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001547}
1548
stefan13f1a0a2016-11-30 07:22:58 -08001549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1550 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1551 200000);
1552}
1553
1554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1555 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1556}
1557
1558TEST_F(WebRtcVoiceEngineTestFake,
1559 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1560 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1561}
1562
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1564 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1565}
1566
1567TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001568 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001569 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1570 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001571 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001572 SetSendParameters(send_parameters_);
1573 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1574 << "Setting max bitrate should keep previous min bitrate.";
1575 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1576 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001577 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001578}
1579
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001580// Test that we can enable NACK with opus as caller.
1581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].AddFeedbackParam(
1586 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1587 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001590 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591}
1592
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001593// Test that we can enable NACK with opus as callee.
1594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001595 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001596 cricket::AudioSendParameters parameters;
1597 parameters.codecs.push_back(kOpusCodec);
1598 parameters.codecs[0].AddFeedbackParam(
1599 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1600 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001602 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001603 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001605
1606 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001607 cricket::StreamParams::CreateLegacy(kSsrcX)));
1608 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001609}
1610
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611// Test that we can enable NACK on receive streams.
1612TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001613 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001614 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001615 cricket::AudioSendParameters parameters;
1616 parameters.codecs.push_back(kOpusCodec);
1617 parameters.codecs[0].AddFeedbackParam(
1618 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1619 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001620 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1621 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1624 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001625}
1626
1627// Test that we can disable NACK.
1628TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001629 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001630 cricket::AudioSendParameters parameters;
1631 parameters.codecs.push_back(kOpusCodec);
1632 parameters.codecs[0].AddFeedbackParam(
1633 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1634 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001635 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001636 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001638 parameters.codecs.clear();
1639 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001640 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001641 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642}
1643
1644// Test that we can disable NACK on receive streams.
1645TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001646 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001648 cricket::AudioSendParameters parameters;
1649 parameters.codecs.push_back(kOpusCodec);
1650 parameters.codecs[0].AddFeedbackParam(
1651 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1652 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001653 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001654 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1655 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001657 parameters.codecs.clear();
1658 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1661 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662}
1663
1664// Test that NACK is enabled on a new receive stream.
1665TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001666 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001667 cricket::AudioSendParameters parameters;
1668 parameters.codecs.push_back(kIsacCodec);
1669 parameters.codecs.push_back(kCn16000Codec);
1670 parameters.codecs[0].AddFeedbackParam(
1671 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1672 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001674 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675
solenberg2100c0b2017-03-01 11:29:29 -08001676 EXPECT_TRUE(AddRecvStream(kSsrcY));
1677 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1678 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1679 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680}
1681
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001682// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001683TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001684 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001685 cricket::AudioSendParameters parameters;
1686 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001687 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001688 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001689}
1690
1691// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001692TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001693 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001694 cricket::AudioSendParameters parameters;
1695 parameters.codecs.push_back(kOpusCodec);
1696 parameters.codecs[0].bitrate = 0;
1697 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001698 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001699 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001700}
1701
1702// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001703TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001704 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 cricket::AudioSendParameters parameters;
1706 parameters.codecs.push_back(kOpusCodec);
1707 parameters.codecs[0].bitrate = 0;
1708 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001710 EXPECT_TRUE(GetCodecFec(kSsrcX));
1711 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001712}
1713
1714// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001715TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001716 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 cricket::AudioSendParameters parameters;
1718 parameters.codecs.push_back(kOpusCodec);
1719 parameters.codecs[0].bitrate = 0;
1720 parameters.codecs[0].params["stereo"] = "1";
1721 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001722 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001723 EXPECT_TRUE(GetCodecFec(kSsrcX));
1724 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001725}
1726
1727// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001728TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001729 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001730 cricket::AudioSendParameters parameters;
1731 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001732 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001733 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001734}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001735
1736// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1737TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001738 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001739 cricket::AudioSendParameters parameters;
1740 parameters.codecs.push_back(kIsacCodec);
1741 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001742 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001743 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001744}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001745
1746// Test that Opus FEC status can be changed.
1747TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001748 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 cricket::AudioSendParameters parameters;
1750 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001752 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001753
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001754 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001755 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001756 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001757}
1758
stefanba4c0e42016-02-04 04:12:24 -08001759TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001760 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001761 cricket::AudioSendParameters send_parameters;
1762 send_parameters.codecs.push_back(kOpusCodec);
1763 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001764 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001765
1766 cricket::AudioRecvParameters recv_parameters;
1767 recv_parameters.codecs.push_back(kIsacCodec);
1768 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001769 EXPECT_TRUE(AddRecvStream(kSsrcX));
1770 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001771 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001772 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001773
ossudedfd282016-06-14 07:12:39 -07001774 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001776 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001777 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001778 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001779}
1780
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001781// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1782TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001783 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 cricket::AudioSendParameters parameters;
1785 parameters.codecs.push_back(kOpusCodec);
1786 parameters.codecs[0].bitrate = 0;
1787 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001788 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001789 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1790 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001791
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001792 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001794 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001795}
1796
1797// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1798TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001799 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 cricket::AudioSendParameters parameters;
1801 parameters.codecs.push_back(kOpusCodec);
1802 parameters.codecs[0].bitrate = 0;
1803 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001804 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001805 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1806 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001807
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001808 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001809 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001810 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001811}
1812
1813// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1814TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001815 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001816 cricket::AudioSendParameters parameters;
1817 parameters.codecs.push_back(kOpusCodec);
1818 parameters.codecs[0].bitrate = 0;
1819 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001820 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001821 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1822 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001823
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001825 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001826 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001827}
1828
1829// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1830TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001831 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001832 cricket::AudioSendParameters parameters;
1833 parameters.codecs.push_back(kOpusCodec);
1834 parameters.codecs[0].bitrate = 0;
1835 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001837 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1838 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001839
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001841 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001842 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001843}
1844
1845// Test 24000 < maxplaybackrate triggers Opus full band mode.
1846TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001847 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001848 cricket::AudioSendParameters parameters;
1849 parameters.codecs.push_back(kOpusCodec);
1850 parameters.codecs[0].bitrate = 0;
1851 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001852 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001853 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1854 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001855
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001856 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001857 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001858 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001859}
1860
1861// Test Opus that without maxplaybackrate, default playback rate is used.
1862TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001863 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001864 cricket::AudioSendParameters parameters;
1865 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001866 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001867 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001868}
1869
1870// Test the with non-Opus, maxplaybackrate has no effect.
1871TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001872 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001873 cricket::AudioSendParameters parameters;
1874 parameters.codecs.push_back(kIsacCodec);
1875 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001877 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001878}
1879
1880// Test maxplaybackrate can be set on two streams.
1881TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001882 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001883 cricket::AudioSendParameters parameters;
1884 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001885 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001886 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001887
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001890 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001891
solenberg2100c0b2017-03-01 11:29:29 -08001892 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1893 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001894}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001895
Minyue Li7100dcd2015-03-27 05:05:59 +01001896// Test that with usedtx=0, Opus DTX is off.
1897TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001898 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001899 cricket::AudioSendParameters parameters;
1900 parameters.codecs.push_back(kOpusCodec);
1901 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001902 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001903 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001904}
1905
1906// Test that with usedtx=1, Opus DTX is on.
1907TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001908 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001909 cricket::AudioSendParameters parameters;
1910 parameters.codecs.push_back(kOpusCodec);
1911 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001912 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001913 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001914}
1915
1916// Test that usedtx=1 works with stereo Opus.
1917TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001918 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001919 cricket::AudioSendParameters parameters;
1920 parameters.codecs.push_back(kOpusCodec);
1921 parameters.codecs[0].params["usedtx"] = "1";
1922 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001923 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001924 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001925}
1926
1927// Test that usedtx=1 does not work with non Opus.
1928TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001929 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001930 cricket::AudioSendParameters parameters;
1931 parameters.codecs.push_back(kIsacCodec);
1932 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001933 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001934 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001935}
1936
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001937// Test that we can switch back and forth between Opus and ISAC with CN.
1938TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001939 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001940
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 cricket::AudioSendParameters opus_parameters;
1942 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001943 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001944 {
solenberg2100c0b2017-03-01 11:29:29 -08001945 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001946 EXPECT_EQ(111, gcodec.pltype);
1947 EXPECT_STREQ("opus", gcodec.plname);
1948 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001950 cricket::AudioSendParameters isac_parameters;
1951 isac_parameters.codecs.push_back(kIsacCodec);
1952 isac_parameters.codecs.push_back(kCn16000Codec);
1953 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001954 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001955 {
solenberg2100c0b2017-03-01 11:29:29 -08001956 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001957 EXPECT_EQ(103, gcodec.pltype);
1958 EXPECT_STREQ("ISAC", gcodec.plname);
1959 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001962 {
solenberg2100c0b2017-03-01 11:29:29 -08001963 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001964 EXPECT_EQ(111, gcodec.pltype);
1965 EXPECT_STREQ("opus", gcodec.plname);
1966 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967}
1968
1969// Test that we handle various ways of specifying bitrate.
1970TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 cricket::AudioSendParameters parameters;
1973 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001974 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001975 {
solenberg2100c0b2017-03-01 11:29:29 -08001976 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001977 EXPECT_EQ(103, gcodec.pltype);
1978 EXPECT_STREQ("ISAC", gcodec.plname);
1979 EXPECT_EQ(32000, gcodec.rate);
1980 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001981
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001984 {
solenberg2100c0b2017-03-01 11:29:29 -08001985 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001986 EXPECT_EQ(103, gcodec.pltype);
1987 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001988 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001989 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001990 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001991 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001992 {
solenberg2100c0b2017-03-01 11:29:29 -08001993 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001994 EXPECT_EQ(103, gcodec.pltype);
1995 EXPECT_STREQ("ISAC", gcodec.plname);
1996 EXPECT_EQ(28000, gcodec.rate);
1997 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001999 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07002000 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002001 {
solenberg2100c0b2017-03-01 11:29:29 -08002002 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07002003 EXPECT_EQ(0, gcodec.pltype);
2004 EXPECT_STREQ("PCMU", gcodec.plname);
2005 EXPECT_EQ(64000, gcodec.rate);
2006 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002007
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002008 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07002009 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002010 {
solenberg2100c0b2017-03-01 11:29:29 -08002011 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07002012 EXPECT_EQ(0, gcodec.pltype);
2013 EXPECT_STREQ("PCMU", gcodec.plname);
2014 EXPECT_EQ(64000, gcodec.rate);
2015 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002016
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002017 parameters.codecs[0] = kOpusCodec;
2018 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07002019 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002020 {
solenberg2100c0b2017-03-01 11:29:29 -08002021 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07002022 EXPECT_EQ(111, gcodec.pltype);
2023 EXPECT_STREQ("opus", gcodec.plname);
2024 EXPECT_EQ(32000, gcodec.rate);
2025 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002026}
2027
Brave Yao5225dd82015-03-26 07:39:19 +08002028// Test that we could set packet size specified in kCodecParamPTime.
2029TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07002030 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002031 cricket::AudioSendParameters parameters;
2032 parameters.codecs.push_back(kOpusCodec);
2033 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002034 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002035 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002036
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002037 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07002038 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002039 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002040
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002041 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07002042 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002043 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002044
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002045 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
2046 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002047 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002048 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002049 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08002050
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002051 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
2052 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07002053 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002054 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002055 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08002056}
2057
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002058// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002060 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002061 cricket::AudioSendParameters parameters;
2062 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002063}
2064
2065// Test that we can set send codecs even with telephone-event codec as the first
2066// one on the list.
2067TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002068 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002069 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002070 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002071 parameters.codecs.push_back(kIsacCodec);
2072 parameters.codecs.push_back(kPcmuCodec);
2073 parameters.codecs[0].id = 98; // DTMF
2074 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002076 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002077 EXPECT_EQ(96, gcodec.pltype);
2078 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002079 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002080}
2081
solenberg31642aa2016-03-14 08:00:37 -07002082// Test that payload type range is limited for telephone-event codec.
2083TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002084 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002085 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002086 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002087 parameters.codecs.push_back(kIsacCodec);
2088 parameters.codecs[0].id = 0; // DTMF
2089 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002090 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002091 EXPECT_TRUE(channel_->CanInsertDtmf());
2092 parameters.codecs[0].id = 128; // DTMF
2093 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2094 EXPECT_FALSE(channel_->CanInsertDtmf());
2095 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002096 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002097 EXPECT_TRUE(channel_->CanInsertDtmf());
2098 parameters.codecs[0].id = -1; // DTMF
2099 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2100 EXPECT_FALSE(channel_->CanInsertDtmf());
2101}
2102
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002103// Test that we can set send codecs even with CN codec as the first
2104// one on the list.
2105TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002106 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002107 cricket::AudioSendParameters parameters;
2108 parameters.codecs.push_back(kCn16000Codec);
2109 parameters.codecs.push_back(kIsacCodec);
2110 parameters.codecs.push_back(kPcmuCodec);
2111 parameters.codecs[0].id = 98; // wideband CN
2112 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002113 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002114 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002115 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2116 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2117 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2118 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002119}
2120
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002121// Test that we set VAD and DTMF types correctly as caller.
2122TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002123 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002124 cricket::AudioSendParameters parameters;
2125 parameters.codecs.push_back(kIsacCodec);
2126 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002128 parameters.codecs.push_back(kCn16000Codec);
2129 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002130 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002131 parameters.codecs[0].id = 96;
2132 parameters.codecs[2].id = 97; // wideband CN
2133 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002134 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002135 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002136 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2137 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2138 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2139 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2140 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2141 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002142 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002143}
2144
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002145// Test that we set VAD and DTMF types correctly as callee.
2146TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002147 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002148 cricket::AudioSendParameters parameters;
2149 parameters.codecs.push_back(kIsacCodec);
2150 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002151 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002152 parameters.codecs.push_back(kCn16000Codec);
2153 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002154 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002155 parameters.codecs[0].id = 96;
2156 parameters.codecs[2].id = 97; // wideband CN
2157 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002158 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002159 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002160 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002161
solenberg2100c0b2017-03-01 11:29:29 -08002162 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002163 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2164 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2165 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2166 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2167 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2168 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002169 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002170}
2171
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002172// Test that we only apply VAD if we have a CN codec that matches the
2173// send codec clockrate.
2174TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002175 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002176 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002178 parameters.codecs.push_back(kIsacCodec);
2179 parameters.codecs.push_back(kCn16000Codec);
2180 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002181 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002182 {
solenberg2100c0b2017-03-01 11:29:29 -08002183 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002184 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2185 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2186 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2187 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2188 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2189 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002190 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002191 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002192 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002193 {
solenberg2100c0b2017-03-01 11:29:29 -08002194 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002195 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2196 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2197 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002198 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002199 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002200 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002201 {
solenberg2100c0b2017-03-01 11:29:29 -08002202 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002203 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2204 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2205 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2206 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2207 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2208 }
Brave Yao5225dd82015-03-26 07:39:19 +08002209 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002210 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002211 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002212 {
solenberg2100c0b2017-03-01 11:29:29 -08002213 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002214 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2215 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2216 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002217}
2218
2219// Test that we perform case-insensitive matching of codec names.
2220TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002221 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002222 cricket::AudioSendParameters parameters;
2223 parameters.codecs.push_back(kIsacCodec);
2224 parameters.codecs.push_back(kPcmuCodec);
2225 parameters.codecs.push_back(kCn16000Codec);
2226 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002227 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002228 parameters.codecs[0].name = "iSaC";
2229 parameters.codecs[0].id = 96;
2230 parameters.codecs[2].id = 97; // wideband CN
2231 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002232 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002233 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002234 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2235 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2236 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2237 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2238 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2239 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002240 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002241}
2242
stefanba4c0e42016-02-04 04:12:24 -08002243class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2244 public:
2245 WebRtcVoiceEngineWithSendSideBweTest()
2246 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2247};
2248
2249TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2250 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002251 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002252 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002253 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2254 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2255 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002256 extension.id);
2257 return;
2258 }
2259 }
2260 FAIL() << "Transport sequence number extension not in header-extension list.";
2261}
2262
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002263// Test support for audio level header extension.
2264TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002265 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002266}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002267TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002268 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002269}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002270
solenbergd4adce42016-11-17 06:26:52 -08002271// Test support for transport sequence number header extension.
2272TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2273 TestSetSendRtpHeaderExtensions(
2274 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002275}
solenbergd4adce42016-11-17 06:26:52 -08002276TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2277 TestSetRecvRtpHeaderExtensions(
2278 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002279}
2280
solenberg1ac56142015-10-13 03:58:19 -07002281// Test that we can create a channel and start sending on it.
2282TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002283 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002284 SetSendParameters(send_parameters_);
2285 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002286 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002287 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002288 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002289}
2290
2291// Test that a channel will send if and only if it has a source and is enabled
2292// for sending.
2293TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002294 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002295 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002296 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002297 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002298 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2299 SetAudioSend(kSsrcX, true, &fake_source_);
2300 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2301 SetAudioSend(kSsrcX, true, nullptr);
2302 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002303}
2304
solenberg94218532016-06-16 10:53:22 -07002305// Test that a channel is muted/unmuted.
2306TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2307 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002308 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002309 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2310 SetAudioSend(kSsrcX, true, nullptr);
2311 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2312 SetAudioSend(kSsrcX, false, nullptr);
2313 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002314}
2315
solenberg6d6e7c52016-04-13 09:07:30 -07002316// Test that SetSendParameters() does not alter a stream's send state.
2317TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2318 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002319 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002320
2321 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002322 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002323 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002324
2325 // Changing RTP header extensions will recreate the AudioSendStream.
2326 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002327 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002328 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002329 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002330
2331 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002332 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002333 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002334
2335 // Changing RTP header extensions will recreate the AudioSendStream.
2336 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002337 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002338 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002339}
2340
solenberg1ac56142015-10-13 03:58:19 -07002341// Test that we can create a channel and start playing out on it.
2342TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002343 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002344 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002345 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002346 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002347 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002348 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349}
2350
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002351// Test that we can add and remove send streams.
2352TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2353 SetupForMultiSendStream();
2354
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002356 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002357
solenbergc96df772015-10-21 13:01:53 -07002358 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002359 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002360 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002361 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002362 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002363 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002364 }
tfarina5237aaf2015-11-10 23:44:30 -08002365 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002366
solenbergc96df772015-10-21 13:01:53 -07002367 // Delete the send streams.
2368 for (uint32_t ssrc : kSsrcs4) {
2369 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002370 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002371 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002372 }
solenbergc96df772015-10-21 13:01:53 -07002373 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002374}
2375
2376// Test SetSendCodecs correctly configure the codecs in all send streams.
2377TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2378 SetupForMultiSendStream();
2379
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002380 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002381 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002383 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002384 }
2385
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002386 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002387 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002388 parameters.codecs.push_back(kIsacCodec);
2389 parameters.codecs.push_back(kCn16000Codec);
2390 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002391 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002392
2393 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002394 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002395 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2396 const auto& send_codec_spec =
2397 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2398 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2399 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2400 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2401 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2402 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002403 }
2404
minyue7a973442016-10-20 03:27:12 -07002405 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002406 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002407 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002408 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002409 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2410 const auto& send_codec_spec =
2411 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2412 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002413 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002414 }
2415}
2416
2417// Test we can SetSend on all send streams correctly.
2418TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2419 SetupForMultiSendStream();
2420
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002421 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002422 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002423 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002424 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002425 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002426 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002427 }
2428
2429 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002430 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002431 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002432 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002433 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002434 }
2435
2436 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002437 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002438 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002439 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002440 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002441 }
2442}
2443
2444// Test we can set the correct statistics on all send streams.
2445TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2446 SetupForMultiSendStream();
2447
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002448 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002449 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002450 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002451 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002452 }
solenberg85a04962015-10-27 03:35:21 -07002453
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002454 // Create a receive stream to check that none of the send streams end up in
2455 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002456 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002457
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002458 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002459 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002460 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002461 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002462
solenberg85a04962015-10-27 03:35:21 -07002463 // Check stats for the added streams.
2464 {
2465 cricket::VoiceMediaInfo info;
2466 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002467
solenberg85a04962015-10-27 03:35:21 -07002468 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002469 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002470 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002471 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002472 }
hbos1acfbd22016-11-17 23:43:29 -08002473 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002474
2475 // We have added one receive stream. We should see empty stats.
2476 EXPECT_EQ(info.receivers.size(), 1u);
2477 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002478 }
solenberg1ac56142015-10-13 03:58:19 -07002479
solenberg2100c0b2017-03-01 11:29:29 -08002480 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002481 {
2482 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002483 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002484 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002485 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002486 EXPECT_EQ(0u, info.receivers.size());
2487 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002488
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002489 // Deliver a new packet - a default receive stream should be created and we
2490 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002491 {
2492 cricket::VoiceMediaInfo info;
2493 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2494 SetAudioReceiveStreamStats();
2495 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002496 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002497 EXPECT_EQ(1u, info.receivers.size());
2498 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002499 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002500 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002501}
2502
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002503// Test that we can add and remove receive streams, and do proper send/playout.
2504// We can receive on multiple streams while sending one stream.
2505TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002506 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002507
solenberg1ac56142015-10-13 03:58:19 -07002508 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002509 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002510 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511
solenberg1ac56142015-10-13 03:58:19 -07002512 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002513 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002514 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002515 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002516
solenberg1ac56142015-10-13 03:58:19 -07002517 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002518 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519
2520 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002521 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2522 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2523 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524
2525 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002526 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002527 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528
2529 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002530 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002531 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2532 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533
aleloi84ef6152016-08-04 05:28:21 -07002534 // Restart playout and make sure recv streams are played out.
2535 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002536 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2537 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538
aleloi84ef6152016-08-04 05:28:21 -07002539 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002540 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2541 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542}
2543
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002545// and start sending on it.
2546TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002547 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002548 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2549 EXPECT_CALL(apm_gc_,
2550 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002551 SetSendParameters(send_parameters_);
2552 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002553 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002554 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002555 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556}
2557
wu@webrtc.org97077a32013-10-25 21:18:33 +00002558TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002559 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002560 EXPECT_CALL(adm_,
2561 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002562 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2563 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002564 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2565 send_parameters_.options.tx_agc_digital_compression_gain =
2566 rtc::Optional<uint16_t>(9);
2567 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2568 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002569 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2570 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2571 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002572 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002573
2574 // Check interaction with adjust_agc_delta. Both should be respected, for
2575 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002576 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002577 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002578 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002579}
2580
wu@webrtc.org97077a32013-10-25 21:18:33 +00002581TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002582 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002583 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2584 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002585 send_parameters_.options.recording_sample_rate =
2586 rtc::Optional<uint32_t>(48000);
2587 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002588 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002589}
2590
minyue6b825df2016-10-31 04:08:32 -07002591TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2592 EXPECT_TRUE(SetupSendStream());
2593 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2594 send_parameters_.options.audio_network_adaptor_config =
2595 rtc::Optional<std::string>("1234");
2596 SetSendParameters(send_parameters_);
2597 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002598 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002599}
2600
2601TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2602 EXPECT_TRUE(SetupSendStream());
2603 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2604 send_parameters_.options.audio_network_adaptor_config =
2605 rtc::Optional<std::string>("1234");
2606 SetSendParameters(send_parameters_);
2607 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002608 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002609 const int initial_num = call_.GetNumCreatedSendStreams();
2610 cricket::AudioOptions options;
2611 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002612 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002613 // AudioSendStream expected to be recreated.
2614 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002615 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002616}
2617
2618TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2619 EXPECT_TRUE(SetupSendStream());
2620 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2621 send_parameters_.options.audio_network_adaptor_config =
2622 rtc::Optional<std::string>("1234");
2623 SetSendParameters(send_parameters_);
2624 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002625 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002626 const int initial_num = call_.GetNumCreatedSendStreams();
2627 cricket::AudioOptions options;
2628 options.audio_network_adaptor = rtc::Optional<bool>();
2629 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2630 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002631 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002632 // AudioSendStream not expected to be recreated.
2633 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2634 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002635 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002636}
2637
michaelt6672b262017-01-11 10:17:59 -08002638class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2639 : public WebRtcVoiceEngineTestFake {
2640 public:
2641 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2642 : WebRtcVoiceEngineTestFake(
2643 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2644 "Enabled/") {}
2645};
2646
2647TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2648 EXPECT_TRUE(SetupSendStream());
2649 cricket::AudioSendParameters parameters;
2650 parameters.codecs.push_back(kOpusCodec);
2651 SetSendParameters(parameters);
2652 const int initial_num = call_.GetNumCreatedSendStreams();
2653 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2654
2655 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2656 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002657 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2658 constexpr int kMinOverheadBps =
2659 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002660
2661 constexpr int kOpusMinBitrateBps = 6000;
2662 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002663 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002664 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002665 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002666 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002667
2668 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2669 parameters.options.audio_network_adaptor_config =
2670 rtc::Optional<std::string>("1234");
2671 SetSendParameters(parameters);
2672
ossu11bfc532017-02-16 05:37:06 -08002673 constexpr int kMinOverheadWithAnaBps =
2674 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002675
2676 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002677 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002678
minyuececec102017-03-27 13:04:25 -07002679 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002680 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002681}
2682
minyuececec102017-03-27 13:04:25 -07002683// This test is similar to
2684// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2685// additional field trial.
2686TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2687 SetRtpSendParameterUpdatesMaxBitrate) {
2688 EXPECT_TRUE(SetupSendStream());
2689 cricket::AudioSendParameters send_parameters;
2690 send_parameters.codecs.push_back(kOpusCodec);
2691 SetSendParameters(send_parameters);
2692
2693 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2694 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2695 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2696
2697 constexpr int kMaxBitrateBps = 6000;
2698 rtp_parameters.encodings[0].max_bitrate_bps =
2699 rtc::Optional<int>(kMaxBitrateBps);
2700 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2701
2702 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2703#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2704 constexpr int kMinOverhead = 3333;
2705#else
2706 constexpr int kMinOverhead = 6666;
2707#endif
2708 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2709}
2710
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002711// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002712// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002714 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002715 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716}
2717
2718TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2719 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002720 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002721 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002722 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002723 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002724 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002725 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002726 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727
solenberg85a04962015-10-27 03:35:21 -07002728 // Check stats for the added streams.
2729 {
2730 cricket::VoiceMediaInfo info;
2731 EXPECT_EQ(true, channel_->GetStats(&info));
2732
2733 // We have added one send stream. We should see the stats we've set.
2734 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002735 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002736 // We have added one receive stream. We should see empty stats.
2737 EXPECT_EQ(info.receivers.size(), 1u);
2738 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2739 }
solenberg1ac56142015-10-13 03:58:19 -07002740
solenberg566ef242015-11-06 15:34:49 -08002741 // Start sending - this affects some reported stats.
2742 {
2743 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002744 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002745 EXPECT_EQ(true, channel_->GetStats(&info));
2746 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002747 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002748 }
2749
solenberg2100c0b2017-03-01 11:29:29 -08002750 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002751 {
2752 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002753 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002754 EXPECT_EQ(true, channel_->GetStats(&info));
2755 EXPECT_EQ(1u, info.senders.size());
2756 EXPECT_EQ(0u, info.receivers.size());
2757 }
solenberg1ac56142015-10-13 03:58:19 -07002758
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002759 // Deliver a new packet - a default receive stream should be created and we
2760 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002761 {
2762 cricket::VoiceMediaInfo info;
2763 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2764 SetAudioReceiveStreamStats();
2765 EXPECT_EQ(true, channel_->GetStats(&info));
2766 EXPECT_EQ(1u, info.senders.size());
2767 EXPECT_EQ(1u, info.receivers.size());
2768 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002769 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002770 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002771}
2772
2773// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002774// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002776 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002777 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2778 EXPECT_TRUE(AddRecvStream(kSsrcY));
2779 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002780}
2781
2782// Test that the local SSRC is the same on sending and receiving channels if the
2783// receive channel is created before the send channel.
2784TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002785 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002786 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002787 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002788 cricket::StreamParams::CreateLegacy(kSsrcX)));
2789 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2790 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
2793// Test that we can properly receive packets.
2794TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002795 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002796 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002798
2799 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2800 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002801}
2802
2803// Test that we can properly receive packets on multiple streams.
2804TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002805 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002806 const uint32_t ssrc1 = 1;
2807 const uint32_t ssrc2 = 2;
2808 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002809 EXPECT_TRUE(AddRecvStream(ssrc1));
2810 EXPECT_TRUE(AddRecvStream(ssrc2));
2811 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002812 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002813 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002814 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002815 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002816 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002817 }
mflodman3d7db262016-04-29 00:57:13 -07002818
2819 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2820 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2821 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2822
2823 EXPECT_EQ(s1.received_packets(), 0);
2824 EXPECT_EQ(s2.received_packets(), 0);
2825 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002826
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002828 EXPECT_EQ(s1.received_packets(), 0);
2829 EXPECT_EQ(s2.received_packets(), 0);
2830 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002831
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002832 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002833 EXPECT_EQ(s1.received_packets(), 1);
2834 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2835 EXPECT_EQ(s2.received_packets(), 0);
2836 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002837
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002838 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002839 EXPECT_EQ(s1.received_packets(), 1);
2840 EXPECT_EQ(s2.received_packets(), 1);
2841 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2842 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002843
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002844 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002845 EXPECT_EQ(s1.received_packets(), 1);
2846 EXPECT_EQ(s2.received_packets(), 1);
2847 EXPECT_EQ(s3.received_packets(), 1);
2848 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002849
mflodman3d7db262016-04-29 00:57:13 -07002850 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2851 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2852 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853}
2854
solenberg2100c0b2017-03-01 11:29:29 -08002855// Test that receiving on an unsignaled stream works (a stream is created).
2856TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002857 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002858 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2859
solenberg7e63ef02015-11-20 00:19:43 -08002860 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002861
2862 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002863 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2864 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002865}
2866
solenberg2100c0b2017-03-01 11:29:29 -08002867// Test that receiving N unsignaled stream works (streams will be created), and
2868// that packets are forwarded to them all.
2869TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002870 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002871 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002872 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2873
solenberg2100c0b2017-03-01 11:29:29 -08002874 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002875 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002876 rtc::SetBE32(&packet[8], ssrc);
2877 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002878
solenberg2100c0b2017-03-01 11:29:29 -08002879 // Verify we have one new stream for each loop iteration.
2880 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002881 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2882 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002883 }
mflodman3d7db262016-04-29 00:57:13 -07002884
solenberg2100c0b2017-03-01 11:29:29 -08002885 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002886 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002887 rtc::SetBE32(&packet[8], ssrc);
2888 DeliverPacket(packet, sizeof(packet));
2889
solenbergebb349d2017-03-13 05:46:15 -07002890 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002891 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2892 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2893 }
2894
2895 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2896 constexpr uint32_t kAnotherSsrc = 667;
2897 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002898 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002899
2900 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002901 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002902 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002903 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002904 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2905 EXPECT_EQ(2, streams[i]->received_packets());
2906 }
2907 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2908 EXPECT_EQ(1, streams[i]->received_packets());
2909 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002910 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002911}
2912
solenberg2100c0b2017-03-01 11:29:29 -08002913// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002914// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002915TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002916 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002917 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002918 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2919
2920 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002921 const uint32_t signaled_ssrc = 1;
2922 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002923 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002924 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002925 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2926 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002927 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002928
2929 // Note that the first unknown SSRC cannot be 0, because we only support
2930 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002931 const uint32_t unsignaled_ssrc = 7011;
2932 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002933 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002934 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2935 packet, sizeof(packet)));
2936 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2937
2938 DeliverPacket(packet, sizeof(packet));
2939 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2940
2941 rtc::SetBE32(&packet[8], signaled_ssrc);
2942 DeliverPacket(packet, sizeof(packet));
2943 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2944 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002945}
2946
solenberg4904fb62017-02-17 12:01:14 -08002947// Two tests to verify that adding a receive stream with the same SSRC as a
2948// previously added unsignaled stream will only recreate underlying stream
2949// objects if the stream parameters have changed.
2950TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2951 EXPECT_TRUE(SetupChannel());
2952
2953 // Spawn unsignaled stream with SSRC=1.
2954 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2955 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2956 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2957 sizeof(kPcmuFrame)));
2958
2959 // Verify that the underlying stream object in Call is not recreated when a
2960 // stream with SSRC=1 is added.
2961 const auto& streams = call_.GetAudioReceiveStreams();
2962 EXPECT_EQ(1, streams.size());
2963 int audio_receive_stream_id = streams.front()->id();
2964 EXPECT_TRUE(AddRecvStream(1));
2965 EXPECT_EQ(1, streams.size());
2966 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2967}
2968
2969TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2970 EXPECT_TRUE(SetupChannel());
2971
2972 // Spawn unsignaled stream with SSRC=1.
2973 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2974 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2975 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2976 sizeof(kPcmuFrame)));
2977
2978 // Verify that the underlying stream object in Call *is* recreated when a
2979 // stream with SSRC=1 is added, and which has changed stream parameters.
2980 const auto& streams = call_.GetAudioReceiveStreams();
2981 EXPECT_EQ(1, streams.size());
2982 int audio_receive_stream_id = streams.front()->id();
2983 cricket::StreamParams stream_params;
2984 stream_params.ssrcs.push_back(1);
2985 stream_params.sync_label = "sync_label";
2986 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2987 EXPECT_EQ(1, streams.size());
2988 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2989}
2990
solenberg0a617e22015-10-20 15:49:38 -07002991// Test that we properly handle failures to add a receive stream.
2992TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002993 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002994 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002995 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996}
2997
solenberg0a617e22015-10-20 15:49:38 -07002998// Test that we properly handle failures to add a send stream.
2999TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07003000 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07003001 voe_.set_fail_create_channel(true);
3002 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3003}
3004
solenberg1ac56142015-10-13 03:58:19 -07003005// Test that AddRecvStream creates new stream.
3006TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003007 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07003009 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07003010 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011}
3012
3013// Test that after adding a recv stream, we do not decode more codecs than
3014// those previously passed into SetRecvCodecs.
3015TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07003016 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003017 cricket::AudioRecvParameters parameters;
3018 parameters.codecs.push_back(kIsacCodec);
3019 parameters.codecs.push_back(kPcmuCodec);
3020 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08003021 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07003022 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
3023 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
3024 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025}
3026
3027// Test that we properly clean up any streams that were added, even if
3028// not explicitly removed.
3029TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07003030 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003031 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07003032 EXPECT_TRUE(AddRecvStream(1));
3033 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
3035 delete channel_;
3036 channel_ = NULL;
3037 EXPECT_EQ(0, voe_.GetNumChannels());
3038}
3039
wu@webrtc.org78187522013-10-07 23:32:02 +00003040TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07003041 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07003042 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00003043}
3044
3045TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07003046 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07003047 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07003048 // Manually delete channel to simulate a failure.
3049 int channel = voe_.GetLastChannel();
3050 EXPECT_EQ(0, voe_.DeleteChannel(channel));
3051 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07003052 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00003053 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07003054 EXPECT_NE(channel, new_channel);
3055 // The last created channel is deleted too.
3056 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00003057}
3058
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003059// Test the InsertDtmf on default send stream as caller.
3060TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08003061 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062}
3063
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003064// Test the InsertDtmf on default send stream as callee
3065TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08003066 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003067}
3068
3069// Test the InsertDtmf on specified send stream as caller.
3070TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08003071 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003072}
3073
3074// Test the InsertDtmf on specified send stream as callee.
3075TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08003076 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077}
3078
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003079TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003080 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003081 EXPECT_CALL(adm_,
3082 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3083 EXPECT_CALL(adm_,
3084 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3085 EXPECT_CALL(adm_,
3086 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003087
solenberg246b8172015-12-08 09:50:23 -08003088 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3089 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003090
solenberg246b8172015-12-08 09:50:23 -08003091 // Nothing set in AudioOptions, so everything should be as default.
3092 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003093 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003094 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003095 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3096 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003097
3098 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003099 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3100 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003101 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003102 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003103
3104 // Turn echo cancellation back on, with settings, and make sure
3105 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003106 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3107 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003108 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003109 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003110
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003111 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3112 // control.
solenberg76377c52017-02-21 00:54:31 -08003113 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3114 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003115 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003116 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003117
3118 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003119 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3120 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003121 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3122 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3123 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003124 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003125
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003126 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003127 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3128 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003129 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003130 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003131
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003132 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003133 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3134 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3135 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3136 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003137 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003138 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003139
3140 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003141 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3142 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3143 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3144 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003145 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3146 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003147 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148
3149 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003150 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3151 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3152 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3153 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3154 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3155 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3156 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003157 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3158 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3159 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3160 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003161 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003162 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003163
solenberg1ac56142015-10-13 03:58:19 -07003164 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003165 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3166 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3167 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3168 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3169 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3170 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3171 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003172 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003173}
3174
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003175TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003176 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003177 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003178 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003179 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003180 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003181 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003182 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003183 EXPECT_CALL(adm_,
3184 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3185 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3186 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3187 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3188 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003189
kwiberg686a8ef2016-02-26 03:00:35 -08003190 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003191 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003192 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003193 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003194 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003195 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003196
3197 // Have to add a stream to make SetSend work.
3198 cricket::StreamParams stream1;
3199 stream1.ssrcs.push_back(1);
3200 channel1->AddSendStream(stream1);
3201 cricket::StreamParams stream2;
3202 stream2.ssrcs.push_back(2);
3203 channel2->AddSendStream(stream2);
3204
3205 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003206 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003207 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3208 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3209 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003210 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3211 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3212 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3213 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3214 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003215 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003216 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003217 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003218 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003219
3220 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003221 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003222 parameters_options_no_ns.options.noise_suppression =
3223 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003224 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3225 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3226 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3227 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3228 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003229 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003230 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003231 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3232 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3233 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003234 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003235
3236 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003237 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003238 parameters_options_no_agc.options.auto_gain_control =
3239 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003240 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3241 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3242 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3243 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3244 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003245 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003246 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3247 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3248 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003249 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003250
solenberg76377c52017-02-21 00:54:31 -08003251 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3252 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3253 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3254 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3255 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003256 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003257
solenberg76377c52017-02-21 00:54:31 -08003258 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3259 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3260 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3261 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3262 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003263 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003264
solenberg76377c52017-02-21 00:54:31 -08003265 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3266 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3267 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3268 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3269 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003270 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003271
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003272 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003273 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3274 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003275 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003276 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003277 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003278 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003279 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3280 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3281 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3282 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3283 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003284 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003285 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3286 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3287 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003288 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003289}
3290
wu@webrtc.orgde305012013-10-31 15:40:38 +00003291// This test verifies DSCP settings are properly applied on voice media channel.
3292TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003293 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003294 cricket::FakeNetworkInterface network_interface;
3295 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003296 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003297
solenberg059fb442016-10-26 05:12:24 -07003298 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3299 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3300
solenbergbc37fc82016-04-04 09:54:44 -07003301 channel.reset(
3302 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003303 channel->SetInterface(&network_interface);
3304 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3305 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3306
3307 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003308 channel.reset(
3309 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003310 channel->SetInterface(&network_interface);
3311 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3312
3313 // Verify that setting the option to false resets the
3314 // DiffServCodePoint.
3315 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003316 channel.reset(
3317 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003318 channel->SetInterface(&network_interface);
3319 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3320 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3321
3322 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003323}
3324
solenberg1ac56142015-10-13 03:58:19 -07003325TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003326 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003327 cricket::WebRtcVoiceMediaChannel* media_channel =
3328 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003329 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003330 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003331 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003332 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3333 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3334 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003335 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003336 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003337}
3338
solenberg1ac56142015-10-13 03:58:19 -07003339TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003340 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003341 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003342 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3343 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3344 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003345 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003346 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003347 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3348 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003349 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003350 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003351 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003352 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003353}
3354
solenberg4bac9c52015-10-09 02:32:53 -07003355TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003356 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003357 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003358 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003359 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003360 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003361 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3362 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3363 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003364}
3365
solenberg2100c0b2017-03-01 11:29:29 -08003366TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003367 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003368
3369 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003370 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003371 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3372
3373 // Should remember the volume "2" which will be set on new unsignaled streams,
3374 // and also set the gain to 2 on existing unsignaled streams.
3375 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3376 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3377
3378 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3379 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3380 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3381 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3382 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3383 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3384
3385 // Setting gain with SSRC=0 should affect all unsignaled streams.
3386 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003387 if (kMaxUnsignaledRecvStreams > 1) {
3388 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3389 }
solenberg2100c0b2017-03-01 11:29:29 -08003390 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3391
3392 // Setting gain on an individual stream affects only that.
3393 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003394 if (kMaxUnsignaledRecvStreams > 1) {
3395 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3396 }
solenberg2100c0b2017-03-01 11:29:29 -08003397 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003398}
3399
pbos8fc7fa72015-07-15 08:02:58 -07003400TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003401 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003402 const std::string kSyncLabel = "AvSyncLabel";
3403
solenbergff976312016-03-30 23:28:51 -07003404 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003405 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3406 sp.sync_label = kSyncLabel;
3407 // Creating two channels to make sure that sync label is set properly for both
3408 // the default voice channel and following ones.
3409 EXPECT_TRUE(channel_->AddRecvStream(sp));
3410 sp.ssrcs[0] += 1;
3411 EXPECT_TRUE(channel_->AddRecvStream(sp));
3412
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003413 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003414 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003415 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003416 << "SyncGroup should be set based on sync_label";
3417 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003418 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003419 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003420}
3421
solenberg3a941542015-11-16 07:34:50 -08003422// TODO(solenberg): Remove, once recv streams are configured through Call.
3423// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003424TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003425 // Test that setting the header extensions results in the expected state
3426 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003427 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003428 ssrcs.push_back(223);
3429 ssrcs.push_back(224);
3430
solenbergff976312016-03-30 23:28:51 -07003431 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003432 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003433 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003434 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003435 cricket::StreamParams::CreateLegacy(ssrc)));
3436 }
3437
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003438 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003439 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003440 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003441 EXPECT_NE(nullptr, s);
3442 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3443 }
3444
3445 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003446 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003447 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003448 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003449 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003450 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003451 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003452 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003453 EXPECT_NE(nullptr, s);
3454 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003455 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3456 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003457 for (const auto& s_ext : s_exts) {
3458 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003459 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003460 }
3461 }
3462 }
3463 }
3464
3465 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003466 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003467 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003468 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003469 EXPECT_NE(nullptr, s);
3470 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3471 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003472}
3473
3474TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3475 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003476 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003477 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003478 static const unsigned char kRtcp[] = {
3479 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3480 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3483 };
jbaucheec21bd2016-03-20 06:15:43 -07003484 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003485
solenbergff976312016-03-30 23:28:51 -07003486 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003487 cricket::WebRtcVoiceMediaChannel* media_channel =
3488 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003489 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003490 EXPECT_TRUE(media_channel->AddRecvStream(
3491 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3492
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003493 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003494 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003495 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003496 EXPECT_EQ(0, s->received_packets());
3497 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3498 EXPECT_EQ(1, s->received_packets());
3499 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3500 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003501}
Minyue2013aec2015-05-13 14:14:42 +02003502
solenberg0a617e22015-10-20 15:49:38 -07003503// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003504// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003505TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003506 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003507 EXPECT_TRUE(AddRecvStream(kSsrcY));
3508 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003509 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003510 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3511 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3512 EXPECT_TRUE(AddRecvStream(kSsrcW));
3513 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003514}
3515
solenberg7602aab2016-11-14 11:30:07 -08003516TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3517 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003518 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003519 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003520 cricket::StreamParams::CreateLegacy(kSsrcY)));
3521 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3522 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3523 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003524 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003525 cricket::StreamParams::CreateLegacy(kSsrcW)));
3526 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3527 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003528}
stefan658910c2015-09-03 05:48:32 -07003529
deadbeef884f5852016-01-15 09:20:04 -08003530TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003531 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003532 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3533 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003534
3535 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003536 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3537 EXPECT_TRUE(AddRecvStream(kSsrcX));
3538 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003539
3540 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003541 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3542 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003543
3544 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003545 channel_->SetRawAudioSink(kSsrcX, nullptr);
3546 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003547}
3548
solenberg2100c0b2017-03-01 11:29:29 -08003549TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003550 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003551 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3552 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003553 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3554 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003555
3556 // Should be able to set a default sink even when no stream exists.
3557 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3558
solenberg2100c0b2017-03-01 11:29:29 -08003559 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3560 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003561 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003562 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003563
3564 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003565 channel_->SetRawAudioSink(kSsrc0, nullptr);
3566 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003567
3568 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003569 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3570 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003571
3572 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003573 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003574 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003575 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3576
3577 // Spawn another unsignaled stream - it should be assigned the default sink
3578 // and the previous unsignaled stream should lose it.
3579 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3580 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3581 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3582 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003583 if (kMaxUnsignaledRecvStreams > 1) {
3584 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3585 }
solenberg2100c0b2017-03-01 11:29:29 -08003586 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3587
3588 // Reset the default sink - the second unsignaled stream should lose it.
3589 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003590 if (kMaxUnsignaledRecvStreams > 1) {
3591 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3592 }
solenberg2100c0b2017-03-01 11:29:29 -08003593 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3594
3595 // Try setting the default sink while two streams exists.
3596 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003597 if (kMaxUnsignaledRecvStreams > 1) {
3598 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3599 }
solenberg2100c0b2017-03-01 11:29:29 -08003600 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3601
3602 // Try setting the sink for the first unsignaled stream using its known SSRC.
3603 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003604 if (kMaxUnsignaledRecvStreams > 1) {
3605 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3606 }
solenberg2100c0b2017-03-01 11:29:29 -08003607 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003608 if (kMaxUnsignaledRecvStreams > 1) {
3609 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3610 }
deadbeef884f5852016-01-15 09:20:04 -08003611}
3612
skvlad7a43d252016-03-22 15:32:27 -07003613// Test that, just like the video channel, the voice channel communicates the
3614// network state to the call.
3615TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003616 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003617
3618 EXPECT_EQ(webrtc::kNetworkUp,
3619 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3620 EXPECT_EQ(webrtc::kNetworkUp,
3621 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3622
3623 channel_->OnReadyToSend(false);
3624 EXPECT_EQ(webrtc::kNetworkDown,
3625 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3626 EXPECT_EQ(webrtc::kNetworkUp,
3627 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3628
3629 channel_->OnReadyToSend(true);
3630 EXPECT_EQ(webrtc::kNetworkUp,
3631 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3632 EXPECT_EQ(webrtc::kNetworkUp,
3633 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3634}
3635
aleloi18e0b672016-10-04 02:45:47 -07003636// Test that playout is still started after changing parameters
3637TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3638 SetupRecvStream();
3639 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003640 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003641
3642 // Changing RTP header extensions will recreate the AudioReceiveStream.
3643 cricket::AudioRecvParameters parameters;
3644 parameters.extensions.push_back(
3645 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3646 channel_->SetRecvParameters(parameters);
3647
solenberg2100c0b2017-03-01 11:29:29 -08003648 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003649}
3650
stefan658910c2015-09-03 05:48:32 -07003651// Tests that the library initializes and shuts down properly.
3652TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003653 // If the VoiceEngine wants to gather available codecs early, that's fine but
3654 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003655 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003656 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003657 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003658 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003659 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003660 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3661 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003662 EXPECT_TRUE(channel != nullptr);
3663 delete channel;
solenbergff976312016-03-30 23:28:51 -07003664}
stefan658910c2015-09-03 05:48:32 -07003665
solenbergff976312016-03-30 23:28:51 -07003666// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003667TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3668 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3669 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3670 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003671 // Return 100ms just in case this function gets called. If we don't,
3672 // we could enter a tight loop since the mock would return 0.
3673 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003674 {
ossuc54071d2016-08-17 02:45:41 -07003675 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003676 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003677 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003678 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003679 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003680 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3681 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3682 EXPECT_TRUE(channel != nullptr);
3683 delete channel;
3684 }
stefan658910c2015-09-03 05:48:32 -07003685}
3686
3687// Tests that the library is configured with the codecs we want.
3688TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003689 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3690 // module.
3691
stefan658910c2015-09-03 05:48:32 -07003692 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003693#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003694 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003695 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003696#endif
3697#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003698 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003699 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003700#endif
3701#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003702 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003703 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003704#endif
3705#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003706 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003707 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003708 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003709 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003710 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003711#endif
solenberg26c8c912015-11-27 04:00:25 -08003712 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003713 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003714 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003715 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003716 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003717 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003718 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3719 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3720 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3721 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3722 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3723 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003724 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003725 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003726 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003727 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003728 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003729 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003730 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003731 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003732 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003733 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003734 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003735 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003736 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003737 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003738 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003739 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003740 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003741 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003742 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003743 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003744 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003745 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003746 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003747
stefan658910c2015-09-03 05:48:32 -07003748 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003749 // TODO(ossu): Why are the payload types of codecs with non-static payload
3750 // type assignments checked here? It shouldn't really matter.
3751 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003752 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003753 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3754 if (codec.name == "CN" && codec.clockrate == 16000) {
3755 EXPECT_EQ(105, codec.id);
3756 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3757 EXPECT_EQ(106, codec.id);
3758 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3759 EXPECT_EQ(103, codec.id);
3760 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3761 EXPECT_EQ(104, codec.id);
3762 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3763 EXPECT_EQ(9, codec.id);
3764 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3765 EXPECT_EQ(126, codec.id);
3766 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3767 // Remove these checks once both send and receive side assigns payload types
3768 // dynamically.
3769 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3770 EXPECT_EQ(113, codec.id);
3771 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3772 EXPECT_EQ(112, codec.id);
3773 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3774 EXPECT_EQ(110, codec.id);
3775 } else if (codec.name == "opus") {
3776 EXPECT_EQ(111, codec.id);
3777 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3778 EXPECT_EQ("10", codec.params.find("minptime")->second);
3779 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3780 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003781 }
3782 }
stefan658910c2015-09-03 05:48:32 -07003783}
3784
3785// Tests that VoE supports at least 32 channels
3786TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003787 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003788 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003789 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003790 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003791 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003792
3793 cricket::VoiceMediaChannel* channels[32];
3794 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003795 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003796 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3797 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003798 if (!channel)
3799 break;
stefan658910c2015-09-03 05:48:32 -07003800 channels[num_channels++] = channel;
3801 }
3802
tfarina5237aaf2015-11-10 23:44:30 -08003803 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003804 EXPECT_EQ(expected, num_channels);
3805
3806 while (num_channels > 0) {
3807 delete channels[--num_channels];
3808 }
stefan658910c2015-09-03 05:48:32 -07003809}
3810
3811// Test that we set our preferred codecs properly.
3812TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003813 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3814 // - Check that our builtin codecs are usable by Channel.
3815 // - The codecs provided by the engine is usable by Channel.
3816 // It does not check that the codecs in the RecvParameters are actually
3817 // what we sent in - though it's probably reasonable to expect so, if
3818 // SetRecvParameters returns true.
3819 // I think it will become clear once audio decoder injection is completed.
3820 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003821 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003822 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003823 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003824 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003825 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3826 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003827 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003828 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003829 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003830}
ossu9def8002017-02-09 05:14:32 -08003831
3832TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3833 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003834 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3835 {48000, 2, 16000, 10000, 20000}};
3836 spec1.info.allow_comfort_noise = false;
3837 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003838 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003839 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3840 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003841 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003842 specs.push_back(webrtc::AudioCodecSpec{
3843 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3844 {16000, 1, 13300}});
3845 specs.push_back(
3846 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3847 specs.push_back(
3848 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003849
3850 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3851 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3852 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3853 .WillOnce(Return(specs));
3854
3855 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3856 auto codecs = engine.recv_codecs();
3857 EXPECT_EQ(11, codecs.size());
3858
3859 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3860 // check the actual values safely, to provide better test results.
3861 auto get_codec =
3862 [&codecs](size_t index) -> const cricket::AudioCodec& {
3863 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3864 if (codecs.size() > index)
3865 return codecs[index];
3866 return missing_codec;
3867 };
3868
3869 // Ensure the general codecs are generated first and in order.
3870 for (size_t i = 0; i != specs.size(); ++i) {
3871 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3872 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3873 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3874 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3875 }
3876
3877 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003878 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003879 auto find_codec =
3880 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3881 for (size_t i = 0; i != codecs.size(); ++i) {
3882 const cricket::AudioCodec& codec = codecs[i];
3883 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3884 codec.clockrate == format.clockrate_hz &&
3885 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003886 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003887 }
3888 }
3889 return -1;
3890 };
3891
3892 // Ensure all supplementary codecs are generated last. Their internal ordering
3893 // is not important.
3894 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3895 const int num_specs = static_cast<int>(specs.size());
3896 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3897 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3898 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3899 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3900 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3901 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3902 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3903}