blob: 5da1d8aba0b41d280ec00ec37ce34543f6a2403a [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"
ossu29b1a8d2016-06-13 07:34:51 -070026#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070027#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070028#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080029#include "webrtc/pc/channel.h"
30#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080031#include "webrtc/test/gtest.h"
32#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
919 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 parameters.codecs[0].id = 127;
921 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800922 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923}
924
925// Test that we can add a codec while playing.
926TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700927 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200928 cricket::AudioRecvParameters parameters;
929 parameters.codecs.push_back(kIsacCodec);
930 parameters.codecs.push_back(kCn16000Codec);
931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700932 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200934 parameters.codecs.push_back(kOpusCodec);
935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800936 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800938 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
940}
941
942TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700943 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000945 // Test that when autobw is enabled, bitrate is kept as the default
946 // value. autobw is enabled for the following tests because the target
947 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
949 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700950 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951
952 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700953 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700956 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957}
958
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000959TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700960 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000962 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963
964 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700965 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
966 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
967 // Rates above the max (56000) should be capped.
968 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700971 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
972 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
973 // Rates above the max (510000) should be capped.
974 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975}
976
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000977TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700978 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000979
980 // Test that we can only set a maximum bitrate for a fixed-rate codec
981 // if it's bigger than the fixed rate.
982
983 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700984 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
985 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
986 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
987 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
988 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
989 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
990 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000991}
992
993TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700994 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200995 const int kDesiredBitrate = 128000;
996 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700997 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200998 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700999 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001000
1001 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001002 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001003
solenberg2100c0b2017-03-01 11:29:29 -08001004 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001005}
1006
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007// Test that bitrate cannot be set for CBR codecs.
1008// Bitrate is ignored if it is higher than the fixed bitrate.
1009// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001010TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001011 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012
1013 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001014 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001015 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001016
1017 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001018 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001019 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001020
1021 send_parameters_.max_bandwidth_bps = 128;
1022 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001023 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024}
1025
skvlade0d46372016-04-07 22:59:22 -07001026// Test that the per-stream bitrate limit and the global
1027// bitrate limit both apply.
1028TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1029 EXPECT_TRUE(SetupSendStream());
1030
1031 // opus, default bitrate == 64000.
1032 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1033 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1034 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1035 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1036
1037 // CBR codecs allow both maximums to exceed the bitrate.
1038 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1039 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1040 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1041 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1042
1043 // CBR codecs don't allow per stream maximums to be too low.
1044 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1045 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1046}
1047
1048// Test that an attempt to set RtpParameters for a stream that does not exist
1049// fails.
1050TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1051 EXPECT_TRUE(SetupChannel());
1052 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001053 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001054 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1055
1056 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001057 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001058}
1059
1060TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001061 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001062 // This test verifies that setting RtpParameters succeeds only if
1063 // the structure contains exactly one encoding.
1064 // TODO(skvlad): Update this test when we start supporting setting parameters
1065 // for each encoding individually.
1066
1067 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001068 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001069 // Two or more encodings should result in failure.
1070 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001072 // Zero encodings should also fail.
1073 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001074 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001075}
1076
1077// Changing the SSRC through RtpParameters is not allowed.
1078TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1079 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001081 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001082 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001083}
1084
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001085// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001086// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001087TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1088 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001089 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001090 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001091 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001092 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001093 ASSERT_EQ(1u, parameters.encodings.size());
1094 ASSERT_TRUE(parameters.encodings[0].active);
1095 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001096 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1097 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001098
1099 // Now change it back to active and verify we resume sending.
1100 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001101 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1102 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001103}
1104
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001105// Test that SetRtpSendParameters configures the correct encoding channel for
1106// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001107TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1108 SetupForMultiSendStream();
1109 // Create send streams.
1110 for (uint32_t ssrc : kSsrcs4) {
1111 EXPECT_TRUE(
1112 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1113 }
1114 // Configure one stream to be limited by the stream config, another to be
1115 // limited by the global max, and the third one with no per-stream limit
1116 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001117 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001118 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1119 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1120 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1121
1122 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1123 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1124 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1125
1126 // Remove the global cap; the streams should switch to their respective
1127 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001128 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001129 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1130 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1131 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1132}
1133
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001134// Test that GetRtpSendParameters returns the currently configured codecs.
1135TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001136 EXPECT_TRUE(SetupSendStream());
1137 cricket::AudioSendParameters parameters;
1138 parameters.codecs.push_back(kIsacCodec);
1139 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001140 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001141
solenberg2100c0b2017-03-01 11:29:29 -08001142 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001143 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001144 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1145 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001146}
1147
deadbeefcb443432016-12-12 11:12:36 -08001148// Test that GetRtpSendParameters returns an SSRC.
1149TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1150 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001151 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001152 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001153 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001154}
1155
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001156// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001158 EXPECT_TRUE(SetupSendStream());
1159 cricket::AudioSendParameters parameters;
1160 parameters.codecs.push_back(kIsacCodec);
1161 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001162 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001163
solenberg2100c0b2017-03-01 11:29:29 -08001164 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001165
1166 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001167 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001168
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001169 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001170 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1171 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001172}
1173
minyuececec102017-03-27 13:04:25 -07001174// Test that max_bitrate_bps in send stream config gets updated correctly when
1175// SetRtpSendParameters is called.
1176TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1177 webrtc::test::ScopedFieldTrials override_field_trials(
1178 "WebRTC-Audio-SendSideBwe/Enabled/");
1179 EXPECT_TRUE(SetupSendStream());
1180 cricket::AudioSendParameters send_parameters;
1181 send_parameters.codecs.push_back(kOpusCodec);
1182 SetSendParameters(send_parameters);
1183
1184 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1185 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1186 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1187
1188 constexpr int kMaxBitrateBps = 6000;
1189 rtp_parameters.encodings[0].max_bitrate_bps =
1190 rtc::Optional<int>(kMaxBitrateBps);
1191 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1192
1193 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1194 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1195}
1196
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001197// Test that GetRtpReceiveParameters returns the currently configured codecs.
1198TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1199 EXPECT_TRUE(SetupRecvStream());
1200 cricket::AudioRecvParameters parameters;
1201 parameters.codecs.push_back(kIsacCodec);
1202 parameters.codecs.push_back(kPcmuCodec);
1203 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1204
1205 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001206 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001207 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1208 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1209 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1210}
1211
deadbeefcb443432016-12-12 11:12:36 -08001212// Test that GetRtpReceiveParameters returns an SSRC.
1213TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1214 EXPECT_TRUE(SetupRecvStream());
1215 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001216 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001217 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001218 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001219}
1220
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001221// Test that if we set/get parameters multiple times, we get the same results.
1222TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1223 EXPECT_TRUE(SetupRecvStream());
1224 cricket::AudioRecvParameters parameters;
1225 parameters.codecs.push_back(kIsacCodec);
1226 parameters.codecs.push_back(kPcmuCodec);
1227 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1228
1229 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001230 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001231
1232 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001233 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001234
1235 // ... And this shouldn't change the params returned by
1236 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001237 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1238 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001239}
1240
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001241// Test that we apply codecs properly.
1242TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001243 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001244 cricket::AudioSendParameters parameters;
1245 parameters.codecs.push_back(kIsacCodec);
1246 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001247 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001248 parameters.codecs[0].id = 96;
1249 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001250 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001251 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001252 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001253 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001254 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1255 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1256 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1257 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001258 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001259 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001260}
1261
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001262// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1263// to apply.
1264TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001265 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001266 cricket::AudioSendParameters parameters;
1267 parameters.codecs.push_back(kIsacCodec);
1268 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001269 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001270 parameters.codecs[0].id = 96;
1271 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001272 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001273 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001274 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001275 // Calling SetSendCodec again with same codec which is already set.
1276 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001277 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001278 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001279}
1280
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001281// Verify that G722 is set with 16000 samples per second to WebRTC.
1282TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001283 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001284 cricket::AudioSendParameters parameters;
1285 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001286 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001287 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001288 EXPECT_STREQ("G722", gcodec.plname);
1289 EXPECT_EQ(1, gcodec.channels);
1290 EXPECT_EQ(16000, gcodec.plfreq);
1291}
1292
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001293// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001294TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001295 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001296 cricket::AudioSendParameters parameters;
1297 parameters.codecs.push_back(kOpusCodec);
1298 parameters.codecs[0].bitrate = 0;
1299 parameters.codecs[0].clockrate = 50000;
1300 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001303// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001304TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001305 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001306 cricket::AudioSendParameters parameters;
1307 parameters.codecs.push_back(kOpusCodec);
1308 parameters.codecs[0].bitrate = 0;
1309 parameters.codecs[0].channels = 0;
1310 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311}
1312
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001313// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].channels = 0;
1320 parameters.codecs[0].params["stereo"] = "1";
1321 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322}
1323
1324// Test that if channel is 1 for opus and there's no stereo, we fail.
1325TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001326 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kOpusCodec);
1329 parameters.codecs[0].bitrate = 0;
1330 parameters.codecs[0].channels = 1;
1331 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
1334// Test that if channel is 1 for opus and stereo=0, we fail.
1335TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001336 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001337 cricket::AudioSendParameters parameters;
1338 parameters.codecs.push_back(kOpusCodec);
1339 parameters.codecs[0].bitrate = 0;
1340 parameters.codecs[0].channels = 1;
1341 parameters.codecs[0].params["stereo"] = "0";
1342 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
1345// Test that if channel is 1 for opus and stereo=1, we fail.
1346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
1351 parameters.codecs[0].channels = 1;
1352 parameters.codecs[0].params["stereo"] = "1";
1353 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
1356// Test that with bitrate=0 and no stereo,
1357// channels and bitrate are 1 and 32000.
1358TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001359 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001363 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001364 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365}
1366
1367// Test that with bitrate=0 and stereo=0,
1368// channels and bitrate are 1 and 32000.
1369TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001370 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001371 cricket::AudioSendParameters parameters;
1372 parameters.codecs.push_back(kOpusCodec);
1373 parameters.codecs[0].bitrate = 0;
1374 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001375 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001376 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001377}
1378
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001379// Test that with bitrate=invalid and stereo=0,
1380// channels and bitrate are 1 and 32000.
1381TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001382 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001383 cricket::AudioSendParameters parameters;
1384 parameters.codecs.push_back(kOpusCodec);
1385 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001386 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001387 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001388 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001389 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001390
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001392 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001393 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001394}
1395
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396// Test that with bitrate=0 and stereo=1,
1397// channels and bitrate are 2 and 64000.
1398TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001399 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 cricket::AudioSendParameters parameters;
1401 parameters.codecs.push_back(kOpusCodec);
1402 parameters.codecs[0].bitrate = 0;
1403 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001404 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001405 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406}
1407
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001408// Test that with bitrate=invalid and stereo=1,
1409// channels and bitrate are 2 and 64000.
1410TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001411 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 cricket::AudioSendParameters parameters;
1413 parameters.codecs.push_back(kOpusCodec);
1414 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001415 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001416 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001417 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001418 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001419
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001422 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001423}
1424
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425// Test that with bitrate=N and stereo unset,
1426// channels and bitrate are 1 and N.
1427TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001428 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001429 cricket::AudioSendParameters parameters;
1430 parameters.codecs.push_back(kOpusCodec);
1431 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001432 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001433 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434 EXPECT_EQ(111, gcodec.pltype);
1435 EXPECT_EQ(96000, gcodec.rate);
1436 EXPECT_STREQ("opus", gcodec.plname);
1437 EXPECT_EQ(1, gcodec.channels);
1438 EXPECT_EQ(48000, gcodec.plfreq);
1439}
1440
1441// Test that with bitrate=N and stereo=0,
1442// channels and bitrate are 1 and N.
1443TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001444 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 cricket::AudioSendParameters parameters;
1446 parameters.codecs.push_back(kOpusCodec);
1447 parameters.codecs[0].bitrate = 30000;
1448 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001449 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001450 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451}
1452
1453// Test that with bitrate=N and without any parameters,
1454// channels and bitrate are 1 and N.
1455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001456 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 cricket::AudioSendParameters parameters;
1458 parameters.codecs.push_back(kOpusCodec);
1459 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001460 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001461 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462}
1463
1464// Test that with bitrate=N and stereo=1,
1465// channels and bitrate are 2 and N.
1466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001467 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 cricket::AudioSendParameters parameters;
1469 parameters.codecs.push_back(kOpusCodec);
1470 parameters.codecs[0].bitrate = 30000;
1471 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001472 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001473 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474}
1475
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001476// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1477// Also test that the "maxaveragebitrate" can't be set to values outside the
1478// range of 6000 and 510000
1479TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001480 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 cricket::AudioSendParameters parameters;
1482 parameters.codecs.push_back(kOpusCodec);
1483 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001487 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001488
1489 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001490 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001491 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001492 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001493
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001494 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001495 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001496 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001497}
1498
stefan13f1a0a2016-11-30 07:22:58 -08001499TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1500 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1501 200000);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1505 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1506}
1507
1508TEST_F(WebRtcVoiceEngineTestFake,
1509 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1510 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1511}
1512
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1514 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1515}
1516
1517TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001518 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001519 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1520 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001521 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001522 SetSendParameters(send_parameters_);
1523 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1524 << "Setting max bitrate should keep previous min bitrate.";
1525 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1526 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001527 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001528}
1529
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001530// Test that we can enable NACK with opus as caller.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001532 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001533 cricket::AudioSendParameters parameters;
1534 parameters.codecs.push_back(kOpusCodec);
1535 parameters.codecs[0].AddFeedbackParam(
1536 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1537 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541}
1542
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001543// Test that we can enable NACK with opus as callee.
1544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001545 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001546 cricket::AudioSendParameters parameters;
1547 parameters.codecs.push_back(kOpusCodec);
1548 parameters.codecs[0].AddFeedbackParam(
1549 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1550 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001552 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001553 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001555
1556 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001557 cricket::StreamParams::CreateLegacy(kSsrcX)));
1558 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001559}
1560
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561// Test that we can enable NACK on receive streams.
1562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001565 cricket::AudioSendParameters parameters;
1566 parameters.codecs.push_back(kOpusCodec);
1567 parameters.codecs[0].AddFeedbackParam(
1568 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1569 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001570 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1571 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001572 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1574 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575}
1576
1577// Test that we can disable NACK.
1578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001579 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 cricket::AudioSendParameters parameters;
1581 parameters.codecs.push_back(kOpusCodec);
1582 parameters.codecs[0].AddFeedbackParam(
1583 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1584 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001585 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001586 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 parameters.codecs.clear();
1589 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
1594// Test that we can disable NACK on receive streams.
1595TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001596 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001597 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 cricket::AudioSendParameters parameters;
1599 parameters.codecs.push_back(kOpusCodec);
1600 parameters.codecs[0].AddFeedbackParam(
1601 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1602 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001603 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001604 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1605 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 parameters.codecs.clear();
1608 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1611 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
1614// Test that NACK is enabled on a new receive stream.
1615TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001616 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 cricket::AudioSendParameters parameters;
1618 parameters.codecs.push_back(kIsacCodec);
1619 parameters.codecs.push_back(kCn16000Codec);
1620 parameters.codecs[0].AddFeedbackParam(
1621 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1622 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001623 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001624 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001625
solenberg2100c0b2017-03-01 11:29:29 -08001626 EXPECT_TRUE(AddRecvStream(kSsrcY));
1627 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1628 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1629 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001630}
1631
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001632// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001633TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001634 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001637 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001638 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001639}
1640
1641// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001642TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001643 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 cricket::AudioSendParameters parameters;
1645 parameters.codecs.push_back(kOpusCodec);
1646 parameters.codecs[0].bitrate = 0;
1647 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001648 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001649 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001650}
1651
1652// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001653TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001654 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001655 cricket::AudioSendParameters parameters;
1656 parameters.codecs.push_back(kOpusCodec);
1657 parameters.codecs[0].bitrate = 0;
1658 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001659 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001660 EXPECT_TRUE(GetCodecFec(kSsrcX));
1661 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001662}
1663
1664// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001665TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
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(kOpusCodec);
1669 parameters.codecs[0].bitrate = 0;
1670 parameters.codecs[0].params["stereo"] = "1";
1671 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001672 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001673 EXPECT_TRUE(GetCodecFec(kSsrcX));
1674 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001675}
1676
1677// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001678TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001679 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 cricket::AudioSendParameters parameters;
1681 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001682 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001683 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001684}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001685
1686// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1687TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001688 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 cricket::AudioSendParameters parameters;
1690 parameters.codecs.push_back(kIsacCodec);
1691 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001694}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001695
1696// Test that Opus FEC status can be changed.
1697TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001698 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001699 cricket::AudioSendParameters parameters;
1700 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001701 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001702 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001703
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001704 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001706 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001707}
1708
stefanba4c0e42016-02-04 04:12:24 -08001709TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001710 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001711 cricket::AudioSendParameters send_parameters;
1712 send_parameters.codecs.push_back(kOpusCodec);
1713 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001714 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001715
1716 cricket::AudioRecvParameters recv_parameters;
1717 recv_parameters.codecs.push_back(kIsacCodec);
1718 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001719 EXPECT_TRUE(AddRecvStream(kSsrcX));
1720 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001721 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001722 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001723
ossudedfd282016-06-14 07:12:39 -07001724 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001725 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001726 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001727 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001728 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001729}
1730
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001731// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1732TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001733 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001734 cricket::AudioSendParameters parameters;
1735 parameters.codecs.push_back(kOpusCodec);
1736 parameters.codecs[0].bitrate = 0;
1737 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001739 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1740 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001741
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001742 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001743 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001744 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001745}
1746
1747// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1748TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001749 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001750 cricket::AudioSendParameters parameters;
1751 parameters.codecs.push_back(kOpusCodec);
1752 parameters.codecs[0].bitrate = 0;
1753 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001754 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001755 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1756 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001757
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001759 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001760 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001761}
1762
1763// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1764TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001765 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 cricket::AudioSendParameters parameters;
1767 parameters.codecs.push_back(kOpusCodec);
1768 parameters.codecs[0].bitrate = 0;
1769 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001770 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001771 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1772 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001773
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001774 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001776 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001777}
1778
1779// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1780TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001781 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001782 cricket::AudioSendParameters parameters;
1783 parameters.codecs.push_back(kOpusCodec);
1784 parameters.codecs[0].bitrate = 0;
1785 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001786 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001787 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1788 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001789
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001790 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001792 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001793}
1794
1795// Test 24000 < maxplaybackrate triggers Opus full band mode.
1796TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001797 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001798 cricket::AudioSendParameters parameters;
1799 parameters.codecs.push_back(kOpusCodec);
1800 parameters.codecs[0].bitrate = 0;
1801 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001803 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1804 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001805
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001806 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001808 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001809}
1810
1811// Test Opus that without maxplaybackrate, default playback rate is used.
1812TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001813 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 cricket::AudioSendParameters parameters;
1815 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001816 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001817 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001818}
1819
1820// Test the with non-Opus, maxplaybackrate has no effect.
1821TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001822 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001823 cricket::AudioSendParameters parameters;
1824 parameters.codecs.push_back(kIsacCodec);
1825 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001827 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001828}
1829
1830// Test maxplaybackrate can be set on two streams.
1831TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001832 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001833 cricket::AudioSendParameters parameters;
1834 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001835 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001836 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001837
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001838 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001839 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001840 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001841
solenberg2100c0b2017-03-01 11:29:29 -08001842 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1843 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001844}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001845
Minyue Li7100dcd2015-03-27 05:05:59 +01001846// Test that with usedtx=0, Opus DTX is off.
1847TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001848 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001849 cricket::AudioSendParameters parameters;
1850 parameters.codecs.push_back(kOpusCodec);
1851 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001852 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001853 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001854}
1855
1856// Test that with usedtx=1, Opus DTX is on.
1857TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001858 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001859 cricket::AudioSendParameters parameters;
1860 parameters.codecs.push_back(kOpusCodec);
1861 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001862 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001863 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001864}
1865
1866// Test that usedtx=1 works with stereo Opus.
1867TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001868 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001869 cricket::AudioSendParameters parameters;
1870 parameters.codecs.push_back(kOpusCodec);
1871 parameters.codecs[0].params["usedtx"] = "1";
1872 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001873 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001874 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001875}
1876
1877// Test that usedtx=1 does not work with non Opus.
1878TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001879 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001880 cricket::AudioSendParameters parameters;
1881 parameters.codecs.push_back(kIsacCodec);
1882 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001883 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001884 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001885}
1886
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001887// Test that we can switch back and forth between Opus and ISAC with CN.
1888TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001889 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001890
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 cricket::AudioSendParameters opus_parameters;
1892 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001893 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001894 {
solenberg2100c0b2017-03-01 11:29:29 -08001895 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001896 EXPECT_EQ(111, gcodec.pltype);
1897 EXPECT_STREQ("opus", gcodec.plname);
1898 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001900 cricket::AudioSendParameters isac_parameters;
1901 isac_parameters.codecs.push_back(kIsacCodec);
1902 isac_parameters.codecs.push_back(kCn16000Codec);
1903 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001904 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001905 {
solenberg2100c0b2017-03-01 11:29:29 -08001906 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001907 EXPECT_EQ(103, gcodec.pltype);
1908 EXPECT_STREQ("ISAC", gcodec.plname);
1909 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910
solenberg059fb442016-10-26 05:12:24 -07001911 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001912 {
solenberg2100c0b2017-03-01 11:29:29 -08001913 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001914 EXPECT_EQ(111, gcodec.pltype);
1915 EXPECT_STREQ("opus", gcodec.plname);
1916 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917}
1918
1919// Test that we handle various ways of specifying bitrate.
1920TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001921 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001922 cricket::AudioSendParameters parameters;
1923 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001924 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001925 {
solenberg2100c0b2017-03-01 11:29:29 -08001926 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001927 EXPECT_EQ(103, gcodec.pltype);
1928 EXPECT_STREQ("ISAC", gcodec.plname);
1929 EXPECT_EQ(32000, gcodec.rate);
1930 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001931
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001932 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001933 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001934 {
solenberg2100c0b2017-03-01 11:29:29 -08001935 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001936 EXPECT_EQ(103, gcodec.pltype);
1937 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001938 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001939 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001942 {
solenberg2100c0b2017-03-01 11:29:29 -08001943 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001944 EXPECT_EQ(103, gcodec.pltype);
1945 EXPECT_STREQ("ISAC", gcodec.plname);
1946 EXPECT_EQ(28000, gcodec.rate);
1947 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001951 {
solenberg2100c0b2017-03-01 11:29:29 -08001952 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001953 EXPECT_EQ(0, gcodec.pltype);
1954 EXPECT_STREQ("PCMU", gcodec.plname);
1955 EXPECT_EQ(64000, gcodec.rate);
1956 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001959 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001960 {
solenberg2100c0b2017-03-01 11:29:29 -08001961 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001962 EXPECT_EQ(0, gcodec.pltype);
1963 EXPECT_STREQ("PCMU", gcodec.plname);
1964 EXPECT_EQ(64000, gcodec.rate);
1965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001967 parameters.codecs[0] = kOpusCodec;
1968 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001969 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001970 {
solenberg2100c0b2017-03-01 11:29:29 -08001971 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001972 EXPECT_EQ(111, gcodec.pltype);
1973 EXPECT_STREQ("opus", gcodec.plname);
1974 EXPECT_EQ(32000, gcodec.rate);
1975 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976}
1977
Brave Yao5225dd82015-03-26 07:39:19 +08001978// Test that we could set packet size specified in kCodecParamPTime.
1979TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001980 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001981 cricket::AudioSendParameters parameters;
1982 parameters.codecs.push_back(kOpusCodec);
1983 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001984 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001985 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001986
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001987 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001988 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001989 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001990
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001991 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001992 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001993 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001994
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001995 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1996 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001997 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001998 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001999 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08002000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002001 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
2002 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07002003 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002004 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002005 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08002006}
2007
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002008// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002009TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002010 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 cricket::AudioSendParameters parameters;
2012 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002013}
2014
2015// Test that we can set send codecs even with telephone-event codec as the first
2016// one on the list.
2017TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002018 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002019 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002020 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002021 parameters.codecs.push_back(kIsacCodec);
2022 parameters.codecs.push_back(kPcmuCodec);
2023 parameters.codecs[0].id = 98; // DTMF
2024 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002025 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002026 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002027 EXPECT_EQ(96, gcodec.pltype);
2028 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002029 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002030}
2031
solenberg31642aa2016-03-14 08:00:37 -07002032// Test that payload type range is limited for telephone-event codec.
2033TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002034 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002035 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002036 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002037 parameters.codecs.push_back(kIsacCodec);
2038 parameters.codecs[0].id = 0; // DTMF
2039 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002040 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002041 EXPECT_TRUE(channel_->CanInsertDtmf());
2042 parameters.codecs[0].id = 128; // DTMF
2043 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2044 EXPECT_FALSE(channel_->CanInsertDtmf());
2045 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002046 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002047 EXPECT_TRUE(channel_->CanInsertDtmf());
2048 parameters.codecs[0].id = -1; // DTMF
2049 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2050 EXPECT_FALSE(channel_->CanInsertDtmf());
2051}
2052
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002053// Test that we can set send codecs even with CN codec as the first
2054// one on the list.
2055TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002056 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002057 cricket::AudioSendParameters parameters;
2058 parameters.codecs.push_back(kCn16000Codec);
2059 parameters.codecs.push_back(kIsacCodec);
2060 parameters.codecs.push_back(kPcmuCodec);
2061 parameters.codecs[0].id = 98; // wideband CN
2062 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002063 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002064 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002065 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2066 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2067 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2068 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002069}
2070
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002071// Test that we set VAD and DTMF types correctly as caller.
2072TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002073 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002074 cricket::AudioSendParameters parameters;
2075 parameters.codecs.push_back(kIsacCodec);
2076 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002077 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002078 parameters.codecs.push_back(kCn16000Codec);
2079 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002080 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002081 parameters.codecs[0].id = 96;
2082 parameters.codecs[2].id = 97; // wideband CN
2083 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002084 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002085 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002086 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2087 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2088 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2089 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2090 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2091 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002092 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002093}
2094
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002095// Test that we set VAD and DTMF types correctly as callee.
2096TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002097 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002098 cricket::AudioSendParameters parameters;
2099 parameters.codecs.push_back(kIsacCodec);
2100 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002101 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002102 parameters.codecs.push_back(kCn16000Codec);
2103 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002104 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002105 parameters.codecs[0].id = 96;
2106 parameters.codecs[2].id = 97; // wideband CN
2107 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002108 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002109 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002110 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002111
solenberg2100c0b2017-03-01 11:29:29 -08002112 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002113 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2114 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2115 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2116 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2117 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2118 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002119 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002120}
2121
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122// Test that we only apply VAD if we have a CN codec that matches the
2123// send codec clockrate.
2124TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002125 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002126 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002127 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002128 parameters.codecs.push_back(kIsacCodec);
2129 parameters.codecs.push_back(kCn16000Codec);
2130 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002131 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002132 {
solenberg2100c0b2017-03-01 11:29:29 -08002133 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002134 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2135 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2136 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2137 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2138 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2139 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002141 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002142 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002143 {
solenberg2100c0b2017-03-01 11:29:29 -08002144 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002145 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2146 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2147 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002149 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002150 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002151 {
solenberg2100c0b2017-03-01 11:29:29 -08002152 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002153 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2154 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2155 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2156 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2157 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2158 }
Brave Yao5225dd82015-03-26 07:39:19 +08002159 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002160 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002161 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002162 {
solenberg2100c0b2017-03-01 11:29:29 -08002163 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002164 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2165 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2166 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167}
2168
2169// Test that we perform case-insensitive matching of codec names.
2170TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002171 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002172 cricket::AudioSendParameters parameters;
2173 parameters.codecs.push_back(kIsacCodec);
2174 parameters.codecs.push_back(kPcmuCodec);
2175 parameters.codecs.push_back(kCn16000Codec);
2176 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002177 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002178 parameters.codecs[0].name = "iSaC";
2179 parameters.codecs[0].id = 96;
2180 parameters.codecs[2].id = 97; // wideband CN
2181 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002182 SetSendParameters(parameters);
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_EQ(96, send_codec_spec.codec_inst.pltype);
2185 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2186 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2187 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2188 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2189 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002190 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002191}
2192
stefanba4c0e42016-02-04 04:12:24 -08002193class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2194 public:
2195 WebRtcVoiceEngineWithSendSideBweTest()
2196 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2197};
2198
2199TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2200 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002201 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002202 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002203 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2204 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2205 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002206 extension.id);
2207 return;
2208 }
2209 }
2210 FAIL() << "Transport sequence number extension not in header-extension list.";
2211}
2212
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002213// Test support for audio level header extension.
2214TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002215 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002216}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002217TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002218 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002219}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002220
solenbergd4adce42016-11-17 06:26:52 -08002221// Test support for transport sequence number header extension.
2222TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2223 TestSetSendRtpHeaderExtensions(
2224 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002225}
solenbergd4adce42016-11-17 06:26:52 -08002226TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2227 TestSetRecvRtpHeaderExtensions(
2228 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002229}
2230
solenberg1ac56142015-10-13 03:58:19 -07002231// Test that we can create a channel and start sending on it.
2232TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002233 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002234 SetSendParameters(send_parameters_);
2235 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002236 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002237 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002238 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002239}
2240
2241// Test that a channel will send if and only if it has a source and is enabled
2242// for sending.
2243TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002244 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002245 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002246 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002247 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002248 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2249 SetAudioSend(kSsrcX, true, &fake_source_);
2250 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2251 SetAudioSend(kSsrcX, true, nullptr);
2252 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002253}
2254
solenberg94218532016-06-16 10:53:22 -07002255// Test that a channel is muted/unmuted.
2256TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2257 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002258 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002259 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2260 SetAudioSend(kSsrcX, true, nullptr);
2261 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2262 SetAudioSend(kSsrcX, false, nullptr);
2263 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002264}
2265
solenberg6d6e7c52016-04-13 09:07:30 -07002266// Test that SetSendParameters() does not alter a stream's send state.
2267TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2268 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002269 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002270
2271 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002272 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002274
2275 // Changing RTP header extensions will recreate the AudioSendStream.
2276 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002277 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002278 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002279 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002280
2281 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002282 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002283 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002284
2285 // Changing RTP header extensions will recreate the AudioSendStream.
2286 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002287 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002288 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002289}
2290
solenberg1ac56142015-10-13 03:58:19 -07002291// Test that we can create a channel and start playing out on it.
2292TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002293 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002294 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002295 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002296 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002297 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002298 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002299}
2300
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002301// Test that we can add and remove send streams.
2302TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2303 SetupForMultiSendStream();
2304
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002306 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002307
solenbergc96df772015-10-21 13:01:53 -07002308 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002309 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002310 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002311 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002312 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002313 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002314 }
tfarina5237aaf2015-11-10 23:44:30 -08002315 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002316
solenbergc96df772015-10-21 13:01:53 -07002317 // Delete the send streams.
2318 for (uint32_t ssrc : kSsrcs4) {
2319 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002320 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002321 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002322 }
solenbergc96df772015-10-21 13:01:53 -07002323 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002324}
2325
2326// Test SetSendCodecs correctly configure the codecs in all send streams.
2327TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2328 SetupForMultiSendStream();
2329
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002330 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002331 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002332 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002333 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002334 }
2335
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002336 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002337 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002338 parameters.codecs.push_back(kIsacCodec);
2339 parameters.codecs.push_back(kCn16000Codec);
2340 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002341 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342
2343 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002344 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002345 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2346 const auto& send_codec_spec =
2347 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2348 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2349 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2350 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2351 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2352 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002353 }
2354
minyue7a973442016-10-20 03:27:12 -07002355 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002356 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002357 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002358 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002359 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2360 const auto& send_codec_spec =
2361 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2362 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002363 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002364 }
2365}
2366
2367// Test we can SetSend on all send streams correctly.
2368TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2369 SetupForMultiSendStream();
2370
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002371 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002372 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002373 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002374 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002375 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002376 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002377 }
2378
2379 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002380 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002381 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002383 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002384 }
2385
2386 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002387 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002388 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002389 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002390 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 }
2392}
2393
2394// Test we can set the correct statistics on all send streams.
2395TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2396 SetupForMultiSendStream();
2397
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002398 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002399 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002400 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002401 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002402 }
solenberg85a04962015-10-27 03:35:21 -07002403
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002404 // Create a receive stream to check that none of the send streams end up in
2405 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002406 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002407
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002408 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002409 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002410 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002411 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002412
solenberg85a04962015-10-27 03:35:21 -07002413 // Check stats for the added streams.
2414 {
2415 cricket::VoiceMediaInfo info;
2416 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002417
solenberg85a04962015-10-27 03:35:21 -07002418 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002419 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002420 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002421 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002422 }
hbos1acfbd22016-11-17 23:43:29 -08002423 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002424
2425 // We have added one receive stream. We should see empty stats.
2426 EXPECT_EQ(info.receivers.size(), 1u);
2427 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002428 }
solenberg1ac56142015-10-13 03:58:19 -07002429
solenberg2100c0b2017-03-01 11:29:29 -08002430 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002431 {
2432 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002433 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002434 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002435 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002436 EXPECT_EQ(0u, info.receivers.size());
2437 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002438
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002439 // Deliver a new packet - a default receive stream should be created and we
2440 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002441 {
2442 cricket::VoiceMediaInfo info;
2443 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2444 SetAudioReceiveStreamStats();
2445 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002446 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002447 EXPECT_EQ(1u, info.receivers.size());
2448 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002449 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002450 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002451}
2452
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002453// Test that we can add and remove receive streams, and do proper send/playout.
2454// We can receive on multiple streams while sending one stream.
2455TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002456 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457
solenberg1ac56142015-10-13 03:58:19 -07002458 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002459 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002460 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461
solenberg1ac56142015-10-13 03:58:19 -07002462 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002463 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002464 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002465 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466
solenberg1ac56142015-10-13 03:58:19 -07002467 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002468 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469
2470 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002471 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2472 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2473 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474
2475 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002476 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002477 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002478
2479 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002480 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2482 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483
aleloi84ef6152016-08-04 05:28:21 -07002484 // Restart playout and make sure recv streams are played out.
2485 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002486 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2487 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002488
aleloi84ef6152016-08-04 05:28:21 -07002489 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002490 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2491 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002492}
2493
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002495// and start sending on it.
2496TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002497 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002498 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2499 EXPECT_CALL(apm_gc_,
2500 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002501 SetSendParameters(send_parameters_);
2502 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002503 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002504 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002505 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506}
2507
wu@webrtc.org97077a32013-10-25 21:18:33 +00002508TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002509 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002510 EXPECT_CALL(adm_,
2511 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002512 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2513 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002514 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2515 send_parameters_.options.tx_agc_digital_compression_gain =
2516 rtc::Optional<uint16_t>(9);
2517 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2518 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002519 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2520 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2521 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002522 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002523
2524 // Check interaction with adjust_agc_delta. Both should be respected, for
2525 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002526 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002527 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002528 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002529}
2530
wu@webrtc.org97077a32013-10-25 21:18:33 +00002531TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002532 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002533 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2534 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002535 send_parameters_.options.recording_sample_rate =
2536 rtc::Optional<uint32_t>(48000);
2537 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002538 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002539}
2540
minyue6b825df2016-10-31 04:08:32 -07002541TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2542 EXPECT_TRUE(SetupSendStream());
2543 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2544 send_parameters_.options.audio_network_adaptor_config =
2545 rtc::Optional<std::string>("1234");
2546 SetSendParameters(send_parameters_);
2547 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002548 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002549}
2550
2551TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2552 EXPECT_TRUE(SetupSendStream());
2553 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2554 send_parameters_.options.audio_network_adaptor_config =
2555 rtc::Optional<std::string>("1234");
2556 SetSendParameters(send_parameters_);
2557 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002558 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002559 const int initial_num = call_.GetNumCreatedSendStreams();
2560 cricket::AudioOptions options;
2561 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002562 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002563 // AudioSendStream expected to be recreated.
2564 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002565 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002566}
2567
2568TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2569 EXPECT_TRUE(SetupSendStream());
2570 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2571 send_parameters_.options.audio_network_adaptor_config =
2572 rtc::Optional<std::string>("1234");
2573 SetSendParameters(send_parameters_);
2574 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002575 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002576 const int initial_num = call_.GetNumCreatedSendStreams();
2577 cricket::AudioOptions options;
2578 options.audio_network_adaptor = rtc::Optional<bool>();
2579 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2580 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002581 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002582 // AudioSendStream not expected to be recreated.
2583 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2584 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002585 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002586}
2587
michaelt6672b262017-01-11 10:17:59 -08002588class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2589 : public WebRtcVoiceEngineTestFake {
2590 public:
2591 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2592 : WebRtcVoiceEngineTestFake(
2593 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2594 "Enabled/") {}
2595};
2596
2597TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2598 EXPECT_TRUE(SetupSendStream());
2599 cricket::AudioSendParameters parameters;
2600 parameters.codecs.push_back(kOpusCodec);
2601 SetSendParameters(parameters);
2602 const int initial_num = call_.GetNumCreatedSendStreams();
2603 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2604
2605 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2606 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002607 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2608 constexpr int kMinOverheadBps =
2609 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002610
2611 constexpr int kOpusMinBitrateBps = 6000;
2612 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002613 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002614 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002615 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002616 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002617
2618 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2619 parameters.options.audio_network_adaptor_config =
2620 rtc::Optional<std::string>("1234");
2621 SetSendParameters(parameters);
2622
ossu11bfc532017-02-16 05:37:06 -08002623 constexpr int kMinOverheadWithAnaBps =
2624 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002625
2626 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002627 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002628
minyuececec102017-03-27 13:04:25 -07002629 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002630 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002631}
2632
minyuececec102017-03-27 13:04:25 -07002633// This test is similar to
2634// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2635// additional field trial.
2636TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2637 SetRtpSendParameterUpdatesMaxBitrate) {
2638 EXPECT_TRUE(SetupSendStream());
2639 cricket::AudioSendParameters send_parameters;
2640 send_parameters.codecs.push_back(kOpusCodec);
2641 SetSendParameters(send_parameters);
2642
2643 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2644 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2645 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2646
2647 constexpr int kMaxBitrateBps = 6000;
2648 rtp_parameters.encodings[0].max_bitrate_bps =
2649 rtc::Optional<int>(kMaxBitrateBps);
2650 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2651
2652 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2653#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2654 constexpr int kMinOverhead = 3333;
2655#else
2656 constexpr int kMinOverhead = 6666;
2657#endif
2658 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2659}
2660
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002661// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002662// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002664 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002665 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002666}
2667
2668TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2669 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002670 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002671 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002672 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002673 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002674 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002675 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002676 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002677
solenberg85a04962015-10-27 03:35:21 -07002678 // Check stats for the added streams.
2679 {
2680 cricket::VoiceMediaInfo info;
2681 EXPECT_EQ(true, channel_->GetStats(&info));
2682
2683 // We have added one send stream. We should see the stats we've set.
2684 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002685 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002686 // We have added one receive stream. We should see empty stats.
2687 EXPECT_EQ(info.receivers.size(), 1u);
2688 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2689 }
solenberg1ac56142015-10-13 03:58:19 -07002690
solenberg566ef242015-11-06 15:34:49 -08002691 // Start sending - this affects some reported stats.
2692 {
2693 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002694 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002695 EXPECT_EQ(true, channel_->GetStats(&info));
2696 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002697 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002698 }
2699
solenberg2100c0b2017-03-01 11:29:29 -08002700 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002701 {
2702 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002703 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002704 EXPECT_EQ(true, channel_->GetStats(&info));
2705 EXPECT_EQ(1u, info.senders.size());
2706 EXPECT_EQ(0u, info.receivers.size());
2707 }
solenberg1ac56142015-10-13 03:58:19 -07002708
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002709 // Deliver a new packet - a default receive stream should be created and we
2710 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002711 {
2712 cricket::VoiceMediaInfo info;
2713 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2714 SetAudioReceiveStreamStats();
2715 EXPECT_EQ(true, channel_->GetStats(&info));
2716 EXPECT_EQ(1u, info.senders.size());
2717 EXPECT_EQ(1u, info.receivers.size());
2718 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002719 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002720 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721}
2722
2723// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002724// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002726 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002727 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2728 EXPECT_TRUE(AddRecvStream(kSsrcY));
2729 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730}
2731
2732// Test that the local SSRC is the same on sending and receiving channels if the
2733// receive channel is created before the send channel.
2734TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002735 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002736 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002738 cricket::StreamParams::CreateLegacy(kSsrcX)));
2739 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2740 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002741}
2742
2743// Test that we can properly receive packets.
2744TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002745 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002746 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002748
2749 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2750 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002751}
2752
2753// Test that we can properly receive packets on multiple streams.
2754TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002755 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002756 const uint32_t ssrc1 = 1;
2757 const uint32_t ssrc2 = 2;
2758 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002759 EXPECT_TRUE(AddRecvStream(ssrc1));
2760 EXPECT_TRUE(AddRecvStream(ssrc2));
2761 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002763 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002764 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002765 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002766 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767 }
mflodman3d7db262016-04-29 00:57:13 -07002768
2769 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2770 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2771 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2772
2773 EXPECT_EQ(s1.received_packets(), 0);
2774 EXPECT_EQ(s2.received_packets(), 0);
2775 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002776
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002777 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002778 EXPECT_EQ(s1.received_packets(), 0);
2779 EXPECT_EQ(s2.received_packets(), 0);
2780 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002781
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002782 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002783 EXPECT_EQ(s1.received_packets(), 1);
2784 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2785 EXPECT_EQ(s2.received_packets(), 0);
2786 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002787
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002789 EXPECT_EQ(s1.received_packets(), 1);
2790 EXPECT_EQ(s2.received_packets(), 1);
2791 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2792 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002793
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002794 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002795 EXPECT_EQ(s1.received_packets(), 1);
2796 EXPECT_EQ(s2.received_packets(), 1);
2797 EXPECT_EQ(s3.received_packets(), 1);
2798 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002799
mflodman3d7db262016-04-29 00:57:13 -07002800 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2801 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2802 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002803}
2804
solenberg2100c0b2017-03-01 11:29:29 -08002805// Test that receiving on an unsignaled stream works (a stream is created).
2806TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002807 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002808 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2809
solenberg7e63ef02015-11-20 00:19:43 -08002810 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002811
2812 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002813 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2814 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002815}
2816
solenberg2100c0b2017-03-01 11:29:29 -08002817// Test that receiving N unsignaled stream works (streams will be created), and
2818// that packets are forwarded to them all.
2819TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002820 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002821 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002822 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2823
solenberg2100c0b2017-03-01 11:29:29 -08002824 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002825 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002826 rtc::SetBE32(&packet[8], ssrc);
2827 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002828
solenberg2100c0b2017-03-01 11:29:29 -08002829 // Verify we have one new stream for each loop iteration.
2830 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002831 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2832 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002833 }
mflodman3d7db262016-04-29 00:57:13 -07002834
solenberg2100c0b2017-03-01 11:29:29 -08002835 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002836 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002837 rtc::SetBE32(&packet[8], ssrc);
2838 DeliverPacket(packet, sizeof(packet));
2839
solenbergebb349d2017-03-13 05:46:15 -07002840 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002841 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2842 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2843 }
2844
2845 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2846 constexpr uint32_t kAnotherSsrc = 667;
2847 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002848 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002849
2850 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002851 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002852 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002853 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002854 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2855 EXPECT_EQ(2, streams[i]->received_packets());
2856 }
2857 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2858 EXPECT_EQ(1, streams[i]->received_packets());
2859 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002860 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002861}
2862
solenberg2100c0b2017-03-01 11:29:29 -08002863// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002864// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002865TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002866 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002867 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002868 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2869
2870 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002871 const uint32_t signaled_ssrc = 1;
2872 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002873 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002874 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002875 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2876 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002877 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002878
2879 // Note that the first unknown SSRC cannot be 0, because we only support
2880 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002881 const uint32_t unsignaled_ssrc = 7011;
2882 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002883 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002884 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2885 packet, sizeof(packet)));
2886 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2887
2888 DeliverPacket(packet, sizeof(packet));
2889 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2890
2891 rtc::SetBE32(&packet[8], signaled_ssrc);
2892 DeliverPacket(packet, sizeof(packet));
2893 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2894 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002895}
2896
solenberg4904fb62017-02-17 12:01:14 -08002897// Two tests to verify that adding a receive stream with the same SSRC as a
2898// previously added unsignaled stream will only recreate underlying stream
2899// objects if the stream parameters have changed.
2900TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2901 EXPECT_TRUE(SetupChannel());
2902
2903 // Spawn unsignaled stream with SSRC=1.
2904 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2905 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2906 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2907 sizeof(kPcmuFrame)));
2908
2909 // Verify that the underlying stream object in Call is not recreated when a
2910 // stream with SSRC=1 is added.
2911 const auto& streams = call_.GetAudioReceiveStreams();
2912 EXPECT_EQ(1, streams.size());
2913 int audio_receive_stream_id = streams.front()->id();
2914 EXPECT_TRUE(AddRecvStream(1));
2915 EXPECT_EQ(1, streams.size());
2916 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2917}
2918
2919TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2920 EXPECT_TRUE(SetupChannel());
2921
2922 // Spawn unsignaled stream with SSRC=1.
2923 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2924 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2925 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2926 sizeof(kPcmuFrame)));
2927
2928 // Verify that the underlying stream object in Call *is* recreated when a
2929 // stream with SSRC=1 is added, and which has changed stream parameters.
2930 const auto& streams = call_.GetAudioReceiveStreams();
2931 EXPECT_EQ(1, streams.size());
2932 int audio_receive_stream_id = streams.front()->id();
2933 cricket::StreamParams stream_params;
2934 stream_params.ssrcs.push_back(1);
2935 stream_params.sync_label = "sync_label";
2936 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2937 EXPECT_EQ(1, streams.size());
2938 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2939}
2940
solenberg0a617e22015-10-20 15:49:38 -07002941// Test that we properly handle failures to add a receive stream.
2942TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002943 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002944 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002945 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946}
2947
solenberg0a617e22015-10-20 15:49:38 -07002948// Test that we properly handle failures to add a send stream.
2949TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002950 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002951 voe_.set_fail_create_channel(true);
2952 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2953}
2954
solenberg1ac56142015-10-13 03:58:19 -07002955// Test that AddRecvStream creates new stream.
2956TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002958 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002959 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002960 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961}
2962
2963// Test that after adding a recv stream, we do not decode more codecs than
2964// those previously passed into SetRecvCodecs.
2965TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002966 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002967 cricket::AudioRecvParameters parameters;
2968 parameters.codecs.push_back(kIsacCodec);
2969 parameters.codecs.push_back(kPcmuCodec);
2970 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002971 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002972 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2973 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2974 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975}
2976
2977// Test that we properly clean up any streams that were added, even if
2978// not explicitly removed.
2979TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002980 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002981 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002982 EXPECT_TRUE(AddRecvStream(1));
2983 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2985 delete channel_;
2986 channel_ = NULL;
2987 EXPECT_EQ(0, voe_.GetNumChannels());
2988}
2989
wu@webrtc.org78187522013-10-07 23:32:02 +00002990TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002991 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002992 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002993}
2994
2995TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002996 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002997 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002998 // Manually delete channel to simulate a failure.
2999 int channel = voe_.GetLastChannel();
3000 EXPECT_EQ(0, voe_.DeleteChannel(channel));
3001 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07003002 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00003003 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07003004 EXPECT_NE(channel, new_channel);
3005 // The last created channel is deleted too.
3006 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00003007}
3008
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003009// Test the InsertDtmf on default send stream as caller.
3010TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08003011 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012}
3013
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003014// Test the InsertDtmf on default send stream as callee
3015TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08003016 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003017}
3018
3019// Test the InsertDtmf on specified send stream as caller.
3020TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08003021 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003022}
3023
3024// Test the InsertDtmf on specified send stream as callee.
3025TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08003026 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027}
3028
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003030 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003031 EXPECT_CALL(adm_,
3032 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3033 EXPECT_CALL(adm_,
3034 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3035 EXPECT_CALL(adm_,
3036 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003037
solenberg246b8172015-12-08 09:50:23 -08003038 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3039 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003040
solenberg246b8172015-12-08 09:50:23 -08003041 // Nothing set in AudioOptions, so everything should be as default.
3042 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003043 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003044 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003045 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3046 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003047
3048 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003049 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3050 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003051 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003052 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053
3054 // Turn echo cancellation back on, with settings, and make sure
3055 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003056 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3057 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003058 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003059 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003060
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003061 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3062 // control.
solenberg76377c52017-02-21 00:54:31 -08003063 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3064 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003065 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003066 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003067
3068 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003069 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3070 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003071 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3072 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3073 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003074 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003075
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003076 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003077 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3078 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003079 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003080 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003081
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003083 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3084 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3085 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3086 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003087 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003088 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003089
3090 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003091 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3092 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3093 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3094 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003095 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3096 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003097 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003098
3099 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003100 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3101 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3102 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3103 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3104 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3105 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3106 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003107 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3108 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3109 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3110 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003111 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003112 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003113
solenberg1ac56142015-10-13 03:58:19 -07003114 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003115 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3116 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3117 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3118 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3119 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3120 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3121 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003122 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003123}
3124
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003125TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003126 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003127 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003128 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003129 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003130 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003131 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003132 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003133 EXPECT_CALL(adm_,
3134 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3135 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3136 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3137 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3138 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003139
kwiberg686a8ef2016-02-26 03:00:35 -08003140 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003141 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003142 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003143 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003144 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003145 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003146
3147 // Have to add a stream to make SetSend work.
3148 cricket::StreamParams stream1;
3149 stream1.ssrcs.push_back(1);
3150 channel1->AddSendStream(stream1);
3151 cricket::StreamParams stream2;
3152 stream2.ssrcs.push_back(2);
3153 channel2->AddSendStream(stream2);
3154
3155 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003156 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003157 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3158 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3159 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003160 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3161 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3162 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3163 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3164 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003165 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003166 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003167 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003168 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003169
3170 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003171 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003172 parameters_options_no_ns.options.noise_suppression =
3173 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003174 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3175 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3176 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3177 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3178 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003179 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003180 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003181 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3182 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3183 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003184 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003185
3186 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003187 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003188 parameters_options_no_agc.options.auto_gain_control =
3189 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003190 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3191 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3192 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3193 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3194 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003195 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003196 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3197 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3198 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003199 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003200
solenberg76377c52017-02-21 00:54:31 -08003201 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3202 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3203 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3204 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3205 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003206 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003207
solenberg76377c52017-02-21 00:54:31 -08003208 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3209 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3210 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3211 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3212 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003213 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003214
solenberg76377c52017-02-21 00:54:31 -08003215 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3216 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3217 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3218 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3219 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003220 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003221
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003222 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003223 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3224 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003225 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003226 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003227 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003228 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003229 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3230 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3231 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3232 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3233 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003234 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003235 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3236 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3237 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003238 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003239}
3240
wu@webrtc.orgde305012013-10-31 15:40:38 +00003241// This test verifies DSCP settings are properly applied on voice media channel.
3242TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003243 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003244 cricket::FakeNetworkInterface network_interface;
3245 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003246 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003247
solenberg059fb442016-10-26 05:12:24 -07003248 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3249 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3250
solenbergbc37fc82016-04-04 09:54:44 -07003251 channel.reset(
3252 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003253 channel->SetInterface(&network_interface);
3254 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3255 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3256
3257 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003258 channel.reset(
3259 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003260 channel->SetInterface(&network_interface);
3261 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3262
3263 // Verify that setting the option to false resets the
3264 // DiffServCodePoint.
3265 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003266 channel.reset(
3267 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003268 channel->SetInterface(&network_interface);
3269 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3270 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3271
3272 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003273}
3274
solenberg1ac56142015-10-13 03:58:19 -07003275TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003276 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003277 cricket::WebRtcVoiceMediaChannel* media_channel =
3278 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003279 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003280 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003281 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003282 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3283 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3284 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003285 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003286 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003287}
3288
solenberg1ac56142015-10-13 03:58:19 -07003289TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003290 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003291 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003292 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3293 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3294 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003295 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003296 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003297 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3298 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003299 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003300 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003301 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003302 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003303}
3304
solenberg4bac9c52015-10-09 02:32:53 -07003305TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003306 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003307 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003308 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003309 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003310 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003311 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3312 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3313 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003314}
3315
solenberg2100c0b2017-03-01 11:29:29 -08003316TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003317 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003318
3319 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003320 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003321 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3322
3323 // Should remember the volume "2" which will be set on new unsignaled streams,
3324 // and also set the gain to 2 on existing unsignaled streams.
3325 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3326 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3327
3328 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3329 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3330 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3331 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3332 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3333 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3334
3335 // Setting gain with SSRC=0 should affect all unsignaled streams.
3336 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003337 if (kMaxUnsignaledRecvStreams > 1) {
3338 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3339 }
solenberg2100c0b2017-03-01 11:29:29 -08003340 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3341
3342 // Setting gain on an individual stream affects only that.
3343 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003344 if (kMaxUnsignaledRecvStreams > 1) {
3345 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3346 }
solenberg2100c0b2017-03-01 11:29:29 -08003347 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003348}
3349
pbos8fc7fa72015-07-15 08:02:58 -07003350TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003351 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003352 const std::string kSyncLabel = "AvSyncLabel";
3353
solenbergff976312016-03-30 23:28:51 -07003354 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003355 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3356 sp.sync_label = kSyncLabel;
3357 // Creating two channels to make sure that sync label is set properly for both
3358 // the default voice channel and following ones.
3359 EXPECT_TRUE(channel_->AddRecvStream(sp));
3360 sp.ssrcs[0] += 1;
3361 EXPECT_TRUE(channel_->AddRecvStream(sp));
3362
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003363 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003364 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003365 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003366 << "SyncGroup should be set based on sync_label";
3367 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003368 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003369 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003370}
3371
solenberg3a941542015-11-16 07:34:50 -08003372// TODO(solenberg): Remove, once recv streams are configured through Call.
3373// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003374TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003375 // Test that setting the header extensions results in the expected state
3376 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003377 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003378 ssrcs.push_back(223);
3379 ssrcs.push_back(224);
3380
solenbergff976312016-03-30 23:28:51 -07003381 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003382 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003383 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003384 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003385 cricket::StreamParams::CreateLegacy(ssrc)));
3386 }
3387
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003388 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003389 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003390 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003391 EXPECT_NE(nullptr, s);
3392 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3393 }
3394
3395 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003396 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003397 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003398 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003399 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003400 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003401 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003402 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003403 EXPECT_NE(nullptr, s);
3404 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003405 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3406 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003407 for (const auto& s_ext : s_exts) {
3408 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003409 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003410 }
3411 }
3412 }
3413 }
3414
3415 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003416 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003417 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003418 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003419 EXPECT_NE(nullptr, s);
3420 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3421 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003422}
3423
3424TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3425 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003426 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003427 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003428 static const unsigned char kRtcp[] = {
3429 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3430 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3433 };
jbaucheec21bd2016-03-20 06:15:43 -07003434 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003435
solenbergff976312016-03-30 23:28:51 -07003436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003437 cricket::WebRtcVoiceMediaChannel* media_channel =
3438 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003439 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003440 EXPECT_TRUE(media_channel->AddRecvStream(
3441 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3442
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003443 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003444 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003445 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003446 EXPECT_EQ(0, s->received_packets());
3447 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3448 EXPECT_EQ(1, s->received_packets());
3449 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3450 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003451}
Minyue2013aec2015-05-13 14:14:42 +02003452
solenberg0a617e22015-10-20 15:49:38 -07003453// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003454// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003455TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003456 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003457 EXPECT_TRUE(AddRecvStream(kSsrcY));
3458 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003459 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003460 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3461 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3462 EXPECT_TRUE(AddRecvStream(kSsrcW));
3463 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003464}
3465
solenberg7602aab2016-11-14 11:30:07 -08003466TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3467 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003468 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003469 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003470 cricket::StreamParams::CreateLegacy(kSsrcY)));
3471 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3472 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3473 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003474 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003475 cricket::StreamParams::CreateLegacy(kSsrcW)));
3476 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3477 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003478}
stefan658910c2015-09-03 05:48:32 -07003479
deadbeef884f5852016-01-15 09:20:04 -08003480TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003481 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003482 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3483 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003484
3485 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003486 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3487 EXPECT_TRUE(AddRecvStream(kSsrcX));
3488 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003489
3490 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003491 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3492 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003493
3494 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003495 channel_->SetRawAudioSink(kSsrcX, nullptr);
3496 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003497}
3498
solenberg2100c0b2017-03-01 11:29:29 -08003499TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003500 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003501 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3502 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003503 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3504 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003505
3506 // Should be able to set a default sink even when no stream exists.
3507 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3508
solenberg2100c0b2017-03-01 11:29:29 -08003509 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3510 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003511 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003512 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003513
3514 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003515 channel_->SetRawAudioSink(kSsrc0, nullptr);
3516 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003517
3518 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003519 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3520 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003521
3522 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003523 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003524 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003525 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3526
3527 // Spawn another unsignaled stream - it should be assigned the default sink
3528 // and the previous unsignaled stream should lose it.
3529 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3530 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3531 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3532 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003533 if (kMaxUnsignaledRecvStreams > 1) {
3534 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3535 }
solenberg2100c0b2017-03-01 11:29:29 -08003536 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3537
3538 // Reset the default sink - the second unsignaled stream should lose it.
3539 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003540 if (kMaxUnsignaledRecvStreams > 1) {
3541 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3542 }
solenberg2100c0b2017-03-01 11:29:29 -08003543 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3544
3545 // Try setting the default sink while two streams exists.
3546 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003547 if (kMaxUnsignaledRecvStreams > 1) {
3548 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3549 }
solenberg2100c0b2017-03-01 11:29:29 -08003550 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3551
3552 // Try setting the sink for the first unsignaled stream using its known SSRC.
3553 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003554 if (kMaxUnsignaledRecvStreams > 1) {
3555 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3556 }
solenberg2100c0b2017-03-01 11:29:29 -08003557 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003558 if (kMaxUnsignaledRecvStreams > 1) {
3559 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3560 }
deadbeef884f5852016-01-15 09:20:04 -08003561}
3562
skvlad7a43d252016-03-22 15:32:27 -07003563// Test that, just like the video channel, the voice channel communicates the
3564// network state to the call.
3565TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003566 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003567
3568 EXPECT_EQ(webrtc::kNetworkUp,
3569 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3570 EXPECT_EQ(webrtc::kNetworkUp,
3571 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3572
3573 channel_->OnReadyToSend(false);
3574 EXPECT_EQ(webrtc::kNetworkDown,
3575 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3576 EXPECT_EQ(webrtc::kNetworkUp,
3577 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3578
3579 channel_->OnReadyToSend(true);
3580 EXPECT_EQ(webrtc::kNetworkUp,
3581 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3582 EXPECT_EQ(webrtc::kNetworkUp,
3583 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3584}
3585
aleloi18e0b672016-10-04 02:45:47 -07003586// Test that playout is still started after changing parameters
3587TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3588 SetupRecvStream();
3589 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003590 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003591
3592 // Changing RTP header extensions will recreate the AudioReceiveStream.
3593 cricket::AudioRecvParameters parameters;
3594 parameters.extensions.push_back(
3595 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3596 channel_->SetRecvParameters(parameters);
3597
solenberg2100c0b2017-03-01 11:29:29 -08003598 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003599}
3600
stefan658910c2015-09-03 05:48:32 -07003601// Tests that the library initializes and shuts down properly.
3602TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003603 // If the VoiceEngine wants to gather available codecs early, that's fine but
3604 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003605 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003606 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003607 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003608 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003609 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003610 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3611 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003612 EXPECT_TRUE(channel != nullptr);
3613 delete channel;
solenbergff976312016-03-30 23:28:51 -07003614}
stefan658910c2015-09-03 05:48:32 -07003615
solenbergff976312016-03-30 23:28:51 -07003616// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003617TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3618 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3619 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3620 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003621 // Return 100ms just in case this function gets called. If we don't,
3622 // we could enter a tight loop since the mock would return 0.
3623 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003624 {
ossuc54071d2016-08-17 02:45:41 -07003625 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003626 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003627 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003628 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003629 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003630 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3631 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3632 EXPECT_TRUE(channel != nullptr);
3633 delete channel;
3634 }
stefan658910c2015-09-03 05:48:32 -07003635}
3636
3637// Tests that the library is configured with the codecs we want.
3638TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003639 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3640 // module.
3641
stefan658910c2015-09-03 05:48:32 -07003642 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003643#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003644 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003645 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003646#endif
3647#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003648 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003649 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003650#endif
3651#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003652 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003653 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003654#endif
3655#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003656 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003657 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003658 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003659 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003660 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003661#endif
solenberg26c8c912015-11-27 04:00:25 -08003662 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003663 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003664 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003665 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003666 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003667 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003668 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3669 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3670 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3671 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3672 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3673 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003674 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003675 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003676 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003677 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003678 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003679 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003680 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003681 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003682 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003683 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003684 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003685 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003686 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003687 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003688 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003689 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003690 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003691 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003692 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003693 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003694 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003695 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003696 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003697
stefan658910c2015-09-03 05:48:32 -07003698 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003699 // TODO(ossu): Why are the payload types of codecs with non-static payload
3700 // type assignments checked here? It shouldn't really matter.
3701 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003702 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003703 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3704 if (codec.name == "CN" && codec.clockrate == 16000) {
3705 EXPECT_EQ(105, codec.id);
3706 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3707 EXPECT_EQ(106, codec.id);
3708 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3709 EXPECT_EQ(103, codec.id);
3710 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3711 EXPECT_EQ(104, codec.id);
3712 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3713 EXPECT_EQ(9, codec.id);
3714 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3715 EXPECT_EQ(126, codec.id);
3716 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3717 // Remove these checks once both send and receive side assigns payload types
3718 // dynamically.
3719 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3720 EXPECT_EQ(113, codec.id);
3721 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3722 EXPECT_EQ(112, codec.id);
3723 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3724 EXPECT_EQ(110, codec.id);
3725 } else if (codec.name == "opus") {
3726 EXPECT_EQ(111, codec.id);
3727 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3728 EXPECT_EQ("10", codec.params.find("minptime")->second);
3729 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3730 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003731 }
3732 }
stefan658910c2015-09-03 05:48:32 -07003733}
3734
3735// Tests that VoE supports at least 32 channels
3736TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003737 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003738 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003739 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003740 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003741 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003742
3743 cricket::VoiceMediaChannel* channels[32];
3744 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003745 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003746 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3747 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003748 if (!channel)
3749 break;
stefan658910c2015-09-03 05:48:32 -07003750 channels[num_channels++] = channel;
3751 }
3752
tfarina5237aaf2015-11-10 23:44:30 -08003753 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003754 EXPECT_EQ(expected, num_channels);
3755
3756 while (num_channels > 0) {
3757 delete channels[--num_channels];
3758 }
stefan658910c2015-09-03 05:48:32 -07003759}
3760
3761// Test that we set our preferred codecs properly.
3762TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003763 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3764 // - Check that our builtin codecs are usable by Channel.
3765 // - The codecs provided by the engine is usable by Channel.
3766 // It does not check that the codecs in the RecvParameters are actually
3767 // what we sent in - though it's probably reasonable to expect so, if
3768 // SetRecvParameters returns true.
3769 // I think it will become clear once audio decoder injection is completed.
3770 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003771 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003772 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003773 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003774 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003775 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3776 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003777 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003778 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003779 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003780}
ossu9def8002017-02-09 05:14:32 -08003781
3782TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3783 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003784 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3785 {48000, 2, 16000, 10000, 20000}};
3786 spec1.info.allow_comfort_noise = false;
3787 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003788 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003789 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3790 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003791 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003792 specs.push_back(webrtc::AudioCodecSpec{
3793 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3794 {16000, 1, 13300}});
3795 specs.push_back(
3796 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3797 specs.push_back(
3798 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003799
3800 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3801 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3802 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3803 .WillOnce(Return(specs));
3804
3805 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3806 auto codecs = engine.recv_codecs();
3807 EXPECT_EQ(11, codecs.size());
3808
3809 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3810 // check the actual values safely, to provide better test results.
3811 auto get_codec =
3812 [&codecs](size_t index) -> const cricket::AudioCodec& {
3813 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3814 if (codecs.size() > index)
3815 return codecs[index];
3816 return missing_codec;
3817 };
3818
3819 // Ensure the general codecs are generated first and in order.
3820 for (size_t i = 0; i != specs.size(); ++i) {
3821 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3822 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3823 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3824 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3825 }
3826
3827 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003828 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003829 auto find_codec =
3830 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3831 for (size_t i = 0; i != codecs.size(); ++i) {
3832 const cricket::AudioCodec& codec = codecs[i];
3833 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3834 codec.clockrate == format.clockrate_hz &&
3835 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003836 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003837 }
3838 }
3839 return -1;
3840 };
3841
3842 // Ensure all supplementary codecs are generated last. Their internal ordering
3843 // is not important.
3844 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3845 const int num_specs = static_cast<int>(specs.size());
3846 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3847 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3848 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3849 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3850 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3851 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3852 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3853}