blob: 75b632016697c9a179e7770df89f82457944e597 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080014#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000015#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080016#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070018#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakemediaengine.h"
20#include "webrtc/media/base/fakenetworkinterface.h"
21#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080022#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010023#include "webrtc/media/engine/fakewebrtccall.h"
24#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
25#include "webrtc/media/engine/webrtcvoiceengine.h"
solenbergbc37fc82016-04-04 09:54:44 -070026#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070027#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080028#include "webrtc/pc/channel.h"
29#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080030#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070031#include "webrtc/test/mock_audio_decoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080032#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
kwiberg1c07c702017-03-27 07:15:49 -070034using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070035using testing::Return;
36using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000037
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020038namespace {
39
solenbergebb349d2017-03-13 05:46:15 -070040constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
41
deadbeef67cf2c12016-04-13 10:07:16 -070042const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
43const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
44const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
45const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
46const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070047const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
48const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080049const cricket::AudioCodec
50 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
51const cricket::AudioCodec
52 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
53
solenberg2100c0b2017-03-01 11:29:29 -080054const uint32_t kSsrc0 = 0;
55const uint32_t kSsrc1 = 1;
56const uint32_t kSsrcX = 0x99;
57const uint32_t kSsrcY = 0x17;
58const uint32_t kSsrcZ = 0x42;
59const uint32_t kSsrcW = 0x02;
60const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
solenberg971cab02016-06-14 10:02:41 -070062constexpr int kRtpHistoryMs = 5000;
63
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064class FakeVoEWrapper : public cricket::VoEWrapper {
65 public:
66 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070067 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 }
69};
skvlad11a9cbf2016-10-07 11:53:05 -070070
solenberg76377c52017-02-21 00:54:31 -080071class MockTransmitMixer : public webrtc::voe::TransmitMixer {
72 public:
73 MockTransmitMixer() = default;
74 virtual ~MockTransmitMixer() = default;
75
76 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
77};
solenberg9a5f032222017-03-15 06:14:12 -070078
79void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
80 RTC_DCHECK(adm);
81 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
82 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
83#if !defined(WEBRTC_IOS)
84 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
85 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
86 ChannelType::kChannelBoth)).WillOnce(Return(0));
87#if defined(WEBRTC_WIN)
88 EXPECT_CALL(*adm, SetRecordingDevice(
89 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
90 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
91 .WillOnce(Return(0));
92#else
93 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
94#endif // #if defined(WEBRTC_WIN)
95 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
96 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
97 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
98 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
99#if defined(WEBRTC_WIN)
100 EXPECT_CALL(*adm, SetPlayoutDevice(
101 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
102 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
103 .WillOnce(Return(0));
104#else
105 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
106#endif // #if defined(WEBRTC_WIN)
107 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
108 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
109 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
110#endif // #if !defined(WEBRTC_IOS)
111 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
112 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
113 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
114 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
115}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200116} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117
solenbergff976312016-03-30 23:28:51 -0700118// Tests that our stub library "works".
119TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700120 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700121 AdmSetupExpectations(&adm);
solenberg059fb442016-10-26 05:12:24 -0700122 StrictMock<webrtc::test::MockAudioProcessing> apm;
123 EXPECT_CALL(apm, ApplyConfig(testing::_));
124 EXPECT_CALL(apm, SetExtraOptions(testing::_));
125 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800126 StrictMock<MockTransmitMixer> transmit_mixer;
127 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
128 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700129 EXPECT_FALSE(voe.IsInited());
130 {
ossuc54071d2016-08-17 02:45:41 -0700131 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -0800132 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700133 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700134 EXPECT_TRUE(voe.IsInited());
135 }
136 EXPECT_FALSE(voe.IsInited());
137}
138
deadbeef884f5852016-01-15 09:20:04 -0800139class FakeAudioSink : public webrtc::AudioSinkInterface {
140 public:
141 void OnData(const Data& audio) override {}
142};
143
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800144class FakeAudioSource : public cricket::AudioSource {
145 void SetSink(Sink* sink) override {}
146};
147
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148class WebRtcVoiceEngineTestFake : public testing::Test {
149 public:
stefanba4c0e42016-02-04 04:12:24 -0800150 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
151
152 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800153 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
154 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
155 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700156 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800157 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700158 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800159 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700160 EXPECT_CALL(apm_, ApplyConfig(testing::_));
161 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
162 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800163 // Default Options.
164 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
165 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
166 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
167 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
168 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
169 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
170 // Init does not overwrite default AGC config.
171 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
172 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
173 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
174 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
175 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
176 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800177 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
178 // the tests here probe the specific set of codecs provided by the builtin
179 // factory. Those tests should probably be moved elsewhere.
180 engine_.reset(new cricket::WebRtcVoiceEngine(
181 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
182 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200183 send_parameters_.codecs.push_back(kPcmuCodec);
184 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800185 // Default Options.
186 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 }
solenberg8189b022016-06-14 12:13:00 -0700188
solenbergff976312016-03-30 23:28:51 -0700189 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700190 EXPECT_CALL(apm_, ApplyConfig(testing::_));
191 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700192 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
193 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200194 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000195 }
solenberg8189b022016-06-14 12:13:00 -0700196
solenbergff976312016-03-30 23:28:51 -0700197 bool SetupRecvStream() {
198 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700199 return false;
200 }
solenberg2100c0b2017-03-01 11:29:29 -0800201 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700202 }
solenberg8189b022016-06-14 12:13:00 -0700203
solenbergff976312016-03-30 23:28:51 -0700204 bool SetupSendStream() {
205 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000206 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 }
solenberg2100c0b2017-03-01 11:29:29 -0800208 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800209 return false;
210 }
solenberg059fb442016-10-26 05:12:24 -0700211 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800212 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 }
solenberg8189b022016-06-14 12:13:00 -0700214
215 bool AddRecvStream(uint32_t ssrc) {
216 EXPECT_TRUE(channel_);
217 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
218 }
219
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000220 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700221 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700222 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800223 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
224 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700225 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800226 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000227 }
solenberg8189b022016-06-14 12:13:00 -0700228
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700230 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000231 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
solenberg8189b022016-06-14 12:13:00 -0700233
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200234 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 }
237
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100238 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
239 const auto* send_stream = call_.GetAudioSendStream(ssrc);
240 EXPECT_TRUE(send_stream);
241 return *send_stream;
242 }
243
deadbeef884f5852016-01-15 09:20:04 -0800244 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
245 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
246 EXPECT_TRUE(recv_stream);
247 return *recv_stream;
248 }
249
solenberg3a941542015-11-16 07:34:50 -0800250 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800251 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800252 }
253
solenberg7add0582015-11-20 09:59:34 -0800254 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800255 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800256 }
257
solenberg059fb442016-10-26 05:12:24 -0700258 void SetSend(bool enable) {
259 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700260 if (enable) {
261 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
262 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
263 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700264 EXPECT_CALL(apm_, ApplyConfig(testing::_));
265 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700266 }
solenberg059fb442016-10-26 05:12:24 -0700267 channel_->SetSend(enable);
268 }
269
270 void SetSendParameters(const cricket::AudioSendParameters& params) {
271 EXPECT_CALL(apm_, ApplyConfig(testing::_));
272 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
273 ASSERT_TRUE(channel_);
274 EXPECT_TRUE(channel_->SetSendParameters(params));
275 }
276
minyue6b825df2016-10-31 04:08:32 -0700277 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
278 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700279 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
280 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700281 if (enable && options) {
282 EXPECT_CALL(apm_, ApplyConfig(testing::_));
283 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
284 }
285 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700286 }
287
solenbergffbbcac2016-11-17 05:25:37 -0800288 void TestInsertDtmf(uint32_t ssrc, bool caller,
289 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700290 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000291 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700292 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000293 // send stream.
294 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800295 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000296 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000297
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700299 SetSendParameters(send_parameters_);
300 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800302 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800303 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700304 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000306
307 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700308 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800309 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800311 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000312 }
313
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800315 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100317 // Test send.
318 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800319 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100320 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800321 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800322 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800323 EXPECT_EQ(codec.id, telephone_event.payload_type);
324 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100325 EXPECT_EQ(2, telephone_event.event_code);
326 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 }
328
329 // Test that send bandwidth is set correctly.
330 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000331 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
332 // |expected_result| is the expected result from SetMaxSendBandwidth().
333 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700334 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
335 int max_bitrate,
336 bool expected_result,
337 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200338 cricket::AudioSendParameters parameters;
339 parameters.codecs.push_back(codec);
340 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700341 if (expected_result) {
342 SetSendParameters(parameters);
343 } else {
344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
345 }
solenberg2100c0b2017-03-01 11:29:29 -0800346 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 }
348
skvlade0d46372016-04-07 22:59:22 -0700349 // Sets the per-stream maximum bitrate limit for the specified SSRC.
350 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700351 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700352 EXPECT_EQ(1UL, parameters.encodings.size());
353
deadbeefe702b302017-02-04 12:09:01 -0800354 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700355 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700356 }
357
solenberg059fb442016-10-26 05:12:24 -0700358 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700359 cricket::AudioSendParameters send_parameters;
360 send_parameters.codecs.push_back(codec);
361 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700362 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700363 }
364
minyue7a973442016-10-20 03:27:12 -0700365 void CheckSendCodec(int32_t ssrc,
366 const char expected_name[],
367 int expected_channels,
368 int expected_bitrate) {
369 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
370 EXPECT_STREQ(expected_name, codec.plname);
371 EXPECT_EQ(expected_channels, codec.channels);
372 EXPECT_EQ(expected_bitrate, codec.rate);
373 }
374
375 int GetOpusMaxPlaybackRate(int32_t ssrc) {
376 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
377 }
378
379 bool GetOpusDtx(int32_t ssrc) {
380 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
381 }
382
383 bool GetCodecFec(int32_t ssrc) {
384 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
385 }
386
skvlade0d46372016-04-07 22:59:22 -0700387 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700388 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
389 }
390
391 int GetCodecPacSize(int32_t ssrc) {
392 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700393 }
394
minyue6b825df2016-10-31 04:08:32 -0700395 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
396 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
397 }
398
skvlade0d46372016-04-07 22:59:22 -0700399 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
400 int global_max,
401 int stream_max,
402 bool expected_result,
403 int expected_codec_bitrate) {
404 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800405 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700406
407 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700408 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800409 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700410
411 // Verify that reading back the parameters gives results
412 // consistent with the Set() result.
413 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800414 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700415 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
416 EXPECT_EQ(expected_result ? stream_max : -1,
417 resulting_parameters.encodings[0].max_bitrate_bps);
418
419 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800420 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700421 }
422
stefan13f1a0a2016-11-30 07:22:58 -0800423 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
424 int expected_min_bitrate_bps,
425 const char* start_bitrate_kbps,
426 int expected_start_bitrate_bps,
427 const char* max_bitrate_kbps,
428 int expected_max_bitrate_bps) {
429 EXPECT_TRUE(SetupSendStream());
430 auto& codecs = send_parameters_.codecs;
431 codecs.clear();
432 codecs.push_back(kOpusCodec);
433 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
435 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
436 SetSendParameters(send_parameters_);
437
438 EXPECT_EQ(expected_min_bitrate_bps,
439 call_.GetConfig().bitrate_config.min_bitrate_bps);
440 EXPECT_EQ(expected_start_bitrate_bps,
441 call_.GetConfig().bitrate_config.start_bitrate_bps);
442 EXPECT_EQ(expected_max_bitrate_bps,
443 call_.GetConfig().bitrate_config.max_bitrate_bps);
444 }
445
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000446 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700447 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000448
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000449 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800450 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000451
452 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700453 send_parameters_.extensions.push_back(
454 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700455 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800456 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000457
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000458 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200459 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700460 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800461 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000462
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000463 // Ensure extension is set properly.
464 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700465 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700466 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800467 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
468 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
469 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000470
solenberg7add0582015-11-20 09:59:34 -0800471 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000472 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800473 cricket::StreamParams::CreateLegacy(kSsrcY)));
474 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
475 call_.GetAudioSendStream(kSsrcY));
476 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
477 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
478 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000479
480 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200481 send_parameters_.codecs.push_back(kPcmuCodec);
482 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700483 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
485 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486 }
487
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000488 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700489 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000491 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800492 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000493
494 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700495 recv_parameters_.extensions.push_back(
496 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800497 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000499
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000500 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800501 recv_parameters_.extensions.clear();
502 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800503 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000504
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000505 // Ensure extension is set properly.
506 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700507 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800509 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
510 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
511 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000512
solenberg7add0582015-11-20 09:59:34 -0800513 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800514 EXPECT_TRUE(AddRecvStream(kSsrcY));
515 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
516 call_.GetAudioReceiveStream(kSsrcY));
517 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
518 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
519 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000520
521 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800522 recv_parameters_.extensions.clear();
523 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
525 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000526 }
527
solenberg85a04962015-10-27 03:35:21 -0700528 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
529 webrtc::AudioSendStream::Stats stats;
530 stats.local_ssrc = 12;
531 stats.bytes_sent = 345;
532 stats.packets_sent = 678;
533 stats.packets_lost = 9012;
534 stats.fraction_lost = 34.56f;
535 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800536 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700537 stats.ext_seqnum = 789;
538 stats.jitter_ms = 12;
539 stats.rtt_ms = 345;
540 stats.audio_level = 678;
541 stats.aec_quality_min = 9.01f;
542 stats.echo_delay_median_ms = 234;
543 stats.echo_delay_std_ms = 567;
544 stats.echo_return_loss = 890;
545 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700546 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800547 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700548 stats.typing_noise_detected = true;
549 return stats;
550 }
551 void SetAudioSendStreamStats() {
552 for (auto* s : call_.GetAudioSendStreams()) {
553 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200554 }
solenberg85a04962015-10-27 03:35:21 -0700555 }
solenberg566ef242015-11-06 15:34:49 -0800556 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
557 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700558 const auto stats = GetAudioSendStreamStats();
559 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
560 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
561 EXPECT_EQ(info.packets_sent, stats.packets_sent);
562 EXPECT_EQ(info.packets_lost, stats.packets_lost);
563 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
564 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800565 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700566 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
567 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
568 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
569 EXPECT_EQ(info.audio_level, stats.audio_level);
570 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
571 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
572 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
573 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
574 EXPECT_EQ(info.echo_return_loss_enhancement,
575 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700576 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800577 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
578 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800579 EXPECT_EQ(info.typing_noise_detected,
580 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700581 }
582
583 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
584 webrtc::AudioReceiveStream::Stats stats;
585 stats.remote_ssrc = 123;
586 stats.bytes_rcvd = 456;
587 stats.packets_rcvd = 768;
588 stats.packets_lost = 101;
589 stats.fraction_lost = 23.45f;
590 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800591 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700592 stats.ext_seqnum = 678;
593 stats.jitter_ms = 901;
594 stats.jitter_buffer_ms = 234;
595 stats.jitter_buffer_preferred_ms = 567;
596 stats.delay_estimate_ms = 890;
597 stats.audio_level = 1234;
598 stats.expand_rate = 5.67f;
599 stats.speech_expand_rate = 8.90f;
600 stats.secondary_decoded_rate = 1.23f;
601 stats.accelerate_rate = 4.56f;
602 stats.preemptive_expand_rate = 7.89f;
603 stats.decoding_calls_to_silence_generator = 12;
604 stats.decoding_calls_to_neteq = 345;
605 stats.decoding_normal = 67890;
606 stats.decoding_plc = 1234;
607 stats.decoding_cng = 5678;
608 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700609 stats.decoding_muted_output = 3456;
610 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200611 return stats;
612 }
613 void SetAudioReceiveStreamStats() {
614 for (auto* s : call_.GetAudioReceiveStreams()) {
615 s->SetStats(GetAudioReceiveStreamStats());
616 }
617 }
618 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700619 const auto stats = GetAudioReceiveStreamStats();
620 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
621 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
622 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
623 EXPECT_EQ(info.packets_lost, stats.packets_lost);
624 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
625 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800626 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700627 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
628 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
629 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200630 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700631 stats.jitter_buffer_preferred_ms);
632 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
633 EXPECT_EQ(info.audio_level, stats.audio_level);
634 EXPECT_EQ(info.expand_rate, stats.expand_rate);
635 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
636 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
637 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
638 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200639 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700640 stats.decoding_calls_to_silence_generator);
641 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
642 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
643 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
644 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
645 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700646 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700647 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200648 }
hbos1acfbd22016-11-17 23:43:29 -0800649 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
650 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
651 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
652 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
653 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
654 codec.ToCodecParameters());
655 }
656 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
657 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
658 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
659 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
660 codec.ToCodecParameters());
661 }
662 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200663
peah8271d042016-11-22 07:24:52 -0800664 bool IsHighPassFilterEnabled() {
665 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
666 }
667
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700669 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700670 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800671 webrtc::test::MockGainControl& apm_gc_;
672 webrtc::test::MockEchoCancellation& apm_ec_;
673 webrtc::test::MockNoiseSuppression& apm_ns_;
674 webrtc::test::MockVoiceDetection& apm_vd_;
675 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700676 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200677 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700679 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700680 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200681 cricket::AudioSendParameters send_parameters_;
682 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800683 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800684 private:
685 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686};
687
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688// Tests that we can create and destroy a channel.
689TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700690 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691}
692
solenberg31fec402016-05-06 02:13:12 -0700693// Test that we can add a send stream and that it has the correct defaults.
694TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
695 EXPECT_TRUE(SetupChannel());
696 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800697 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
698 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
699 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700700 EXPECT_EQ("", config.rtp.c_name);
701 EXPECT_EQ(0u, config.rtp.extensions.size());
702 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
703 config.send_transport);
704}
705
706// Test that we can add a receive stream and that it has the correct defaults.
707TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
708 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800709 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700710 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800711 GetRecvStreamConfig(kSsrcX);
712 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700713 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
714 EXPECT_FALSE(config.rtp.transport_cc);
715 EXPECT_EQ(0u, config.rtp.extensions.size());
716 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
717 config.rtcp_send_transport);
718 EXPECT_EQ("", config.sync_group);
719}
720
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700722// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700723// TODO(ossu): This test should move into a separate builtin audio codecs
724// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700725TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700726 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 ASSERT_FALSE(codecs.empty());
728 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
729 EXPECT_EQ(48000, codecs[0].clockrate);
730 EXPECT_EQ(2, codecs[0].channels);
731 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732}
733
stefanba4c0e42016-02-04 04:12:24 -0800734TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700735 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800736 bool opus_found = false;
737 for (cricket::AudioCodec codec : codecs) {
738 if (codec.name == "opus") {
739 EXPECT_TRUE(HasTransportCc(codec));
740 opus_found = true;
741 }
742 }
743 EXPECT_TRUE(opus_found);
744}
745
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746// Tests that we can find codecs by name or id, and that we interpret the
747// clockrate and bitrate fields properly.
748TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
749 cricket::AudioCodec codec;
750 webrtc::CodecInst codec_inst;
751 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800752 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000753 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800754 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800756 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
757 &codec_inst));
758 // Find telephone-event with explicit clockrate and 0 bitrate.
759 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800760 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 // Find ISAC with a different payload id.
762 codec = kIsacCodec;
763 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800764 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 EXPECT_EQ(codec.id, codec_inst.pltype);
766 // Find PCMU with a 0 clockrate.
767 codec = kPcmuCodec;
768 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800769 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 EXPECT_EQ(codec.id, codec_inst.pltype);
771 EXPECT_EQ(8000, codec_inst.plfreq);
772 // Find PCMU with a 0 bitrate.
773 codec = kPcmuCodec;
774 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800775 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 EXPECT_EQ(codec.id, codec_inst.pltype);
777 EXPECT_EQ(64000, codec_inst.rate);
778 // Find ISAC with an explicit bitrate.
779 codec = kIsacCodec;
780 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800781 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 EXPECT_EQ(codec.id, codec_inst.pltype);
783 EXPECT_EQ(32000, codec_inst.rate);
784}
785
786// Test that we set our inbound codecs properly, including changing PT.
787TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700788 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200789 cricket::AudioRecvParameters parameters;
790 parameters.codecs.push_back(kIsacCodec);
791 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800792 parameters.codecs.push_back(kTelephoneEventCodec1);
793 parameters.codecs.push_back(kTelephoneEventCodec2);
794 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200795 parameters.codecs[2].id = 126;
796 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800797 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700798 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
799 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
800 {{0, {"PCMU", 8000, 1}},
801 {106, {"ISAC", 16000, 1}},
802 {126, {"telephone-event", 8000, 1}},
803 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that we fail to set an unknown inbound codec.
807TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700808 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200809 cricket::AudioRecvParameters parameters;
810 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700811 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200812 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813}
814
815// Test that we fail if we have duplicate types in the inbound list.
816TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700817 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200818 cricket::AudioRecvParameters parameters;
819 parameters.codecs.push_back(kIsacCodec);
820 parameters.codecs.push_back(kCn16000Codec);
821 parameters.codecs[1].id = kIsacCodec.id;
822 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that we can decode OPUS without stereo parameters.
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
830 parameters.codecs.push_back(kPcmuCodec);
831 parameters.codecs.push_back(kOpusCodec);
832 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800833 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700834 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
835 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
836 {{0, {"PCMU", 8000, 1}},
837 {103, {"ISAC", 16000, 1}},
838 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that we can decode OPUS with stereo = 0.
842TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700843 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200844 cricket::AudioRecvParameters parameters;
845 parameters.codecs.push_back(kIsacCodec);
846 parameters.codecs.push_back(kPcmuCodec);
847 parameters.codecs.push_back(kOpusCodec);
848 parameters.codecs[2].params["stereo"] = "0";
849 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800850 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700851 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
852 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
853 {{0, {"PCMU", 8000, 1}},
854 {103, {"ISAC", 16000, 1}},
855 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856}
857
858// Test that we can decode OPUS with stereo = 1.
859TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700860 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200861 cricket::AudioRecvParameters parameters;
862 parameters.codecs.push_back(kIsacCodec);
863 parameters.codecs.push_back(kPcmuCodec);
864 parameters.codecs.push_back(kOpusCodec);
865 parameters.codecs[2].params["stereo"] = "1";
866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800867 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700868 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
869 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
870 {{0, {"PCMU", 8000, 1}},
871 {103, {"ISAC", 16000, 1}},
872 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000873}
874
875// Test that changes to recv codecs are applied to all streams.
876TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700877 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200878 cricket::AudioRecvParameters parameters;
879 parameters.codecs.push_back(kIsacCodec);
880 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800881 parameters.codecs.push_back(kTelephoneEventCodec1);
882 parameters.codecs.push_back(kTelephoneEventCodec2);
883 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200884 parameters.codecs[2].id = 126;
885 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700886 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
887 EXPECT_TRUE(AddRecvStream(ssrc));
888 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
889 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
890 {{0, {"PCMU", 8000, 1}},
891 {106, {"ISAC", 16000, 1}},
892 {126, {"telephone-event", 8000, 1}},
893 {107, {"telephone-event", 32000, 1}}})));
894 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895}
896
897TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700898 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200899 cricket::AudioRecvParameters parameters;
900 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800901 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200902 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903
solenberg2100c0b2017-03-01 11:29:29 -0800904 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800905 ASSERT_EQ(1, dm.count(106));
906 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907}
908
909// Test that we can apply the same set of codecs again while playing.
910TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700911 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200912 cricket::AudioRecvParameters parameters;
913 parameters.codecs.push_back(kIsacCodec);
914 parameters.codecs.push_back(kCn16000Codec);
915 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700916 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200917 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918
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
deadbeef3bc15102017-04-20 19:25:07 -07001241// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1242// aren't signaled. It should return an empty "RtpEncodingParameters" when
1243// configured to receive an unsignaled stream and no packets have been received
1244// yet, and start returning the SSRC once a packet has been received.
1245TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1246 ASSERT_TRUE(SetupChannel());
1247 // Call necessary methods to configure receiving a default stream as
1248 // soon as it arrives.
1249 cricket::AudioRecvParameters parameters;
1250 parameters.codecs.push_back(kIsacCodec);
1251 parameters.codecs.push_back(kPcmuCodec);
1252 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1253
1254 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1255 // stream. Should return nothing.
1256 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1257
1258 // Set a sink for an unsignaled stream.
1259 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1260 // Value of "0" means "unsignaled stream".
1261 channel_->SetRawAudioSink(0, std::move(fake_sink));
1262
1263 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1264 // in this method means "unsignaled stream".
1265 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1266 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1267 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1268
1269 // Receive PCMU packet (SSRC=1).
1270 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1271
1272 // The |ssrc| member should still be unset.
1273 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1274 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1275 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1276}
1277
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278// Test that we apply codecs properly.
1279TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001280 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001281 cricket::AudioSendParameters parameters;
1282 parameters.codecs.push_back(kIsacCodec);
1283 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001284 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 parameters.codecs[0].id = 96;
1286 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001287 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001288 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001289 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001290 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001291 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1292 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1293 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1294 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001295 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001296 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001297}
1298
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001299// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1300// to apply.
1301TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001302 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001303 cricket::AudioSendParameters parameters;
1304 parameters.codecs.push_back(kIsacCodec);
1305 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001306 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 parameters.codecs[0].id = 96;
1308 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001309 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001310 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001311 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001312 // Calling SetSendCodec again with same codec which is already set.
1313 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001314 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001315 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001316}
1317
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001318// Verify that G722 is set with 16000 samples per second to WebRTC.
1319TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
solenbergff976312016-03-30 23:28:51 -07001320 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001321 cricket::AudioSendParameters parameters;
1322 parameters.codecs.push_back(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001323 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001324 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001325 EXPECT_STREQ("G722", gcodec.plname);
1326 EXPECT_EQ(1, gcodec.channels);
1327 EXPECT_EQ(16000, gcodec.plfreq);
1328}
1329
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001330// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001332 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001333 cricket::AudioSendParameters parameters;
1334 parameters.codecs.push_back(kOpusCodec);
1335 parameters.codecs[0].bitrate = 0;
1336 parameters.codecs[0].clockrate = 50000;
1337 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001338}
1339
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001340// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001341TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001342 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001343 cricket::AudioSendParameters parameters;
1344 parameters.codecs.push_back(kOpusCodec);
1345 parameters.codecs[0].bitrate = 0;
1346 parameters.codecs[0].channels = 0;
1347 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348}
1349
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001350// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001351TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001352 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001353 cricket::AudioSendParameters parameters;
1354 parameters.codecs.push_back(kOpusCodec);
1355 parameters.codecs[0].bitrate = 0;
1356 parameters.codecs[0].channels = 0;
1357 parameters.codecs[0].params["stereo"] = "1";
1358 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001359}
1360
1361// Test that if channel is 1 for opus and there's no stereo, we fail.
1362TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001363 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001364 cricket::AudioSendParameters parameters;
1365 parameters.codecs.push_back(kOpusCodec);
1366 parameters.codecs[0].bitrate = 0;
1367 parameters.codecs[0].channels = 1;
1368 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001369}
1370
1371// Test that if channel is 1 for opus and stereo=0, we fail.
1372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].bitrate = 0;
1377 parameters.codecs[0].channels = 1;
1378 parameters.codecs[0].params["stereo"] = "0";
1379 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001380}
1381
1382// Test that if channel is 1 for opus and stereo=1, we fail.
1383TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001384 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001385 cricket::AudioSendParameters parameters;
1386 parameters.codecs.push_back(kOpusCodec);
1387 parameters.codecs[0].bitrate = 0;
1388 parameters.codecs[0].channels = 1;
1389 parameters.codecs[0].params["stereo"] = "1";
1390 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001391}
1392
1393// Test that with bitrate=0 and no stereo,
1394// channels and bitrate are 1 and 32000.
1395TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001396 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 cricket::AudioSendParameters parameters;
1398 parameters.codecs.push_back(kOpusCodec);
1399 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001400 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001401 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001402}
1403
1404// Test that with bitrate=0 and stereo=0,
1405// channels and bitrate are 1 and 32000.
1406TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001407 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001408 cricket::AudioSendParameters parameters;
1409 parameters.codecs.push_back(kOpusCodec);
1410 parameters.codecs[0].bitrate = 0;
1411 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001412 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001413 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414}
1415
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001416// Test that with bitrate=invalid and stereo=0,
1417// channels and bitrate are 1 and 32000.
1418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001423 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001424 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001426 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001427
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001429 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001430 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001431}
1432
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433// Test that with bitrate=0 and stereo=1,
1434// channels and bitrate are 2 and 64000.
1435TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001436 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001437 cricket::AudioSendParameters parameters;
1438 parameters.codecs.push_back(kOpusCodec);
1439 parameters.codecs[0].bitrate = 0;
1440 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001441 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001442 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443}
1444
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001445// Test that with bitrate=invalid and stereo=1,
1446// channels and bitrate are 2 and 64000.
1447TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001448 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 cricket::AudioSendParameters parameters;
1450 parameters.codecs.push_back(kOpusCodec);
1451 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001452 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001453 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001454 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001455 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001456
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001458 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001459 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001460}
1461
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462// Test that with bitrate=N and stereo unset,
1463// channels and bitrate are 1 and N.
1464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001465 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001466 cricket::AudioSendParameters parameters;
1467 parameters.codecs.push_back(kOpusCodec);
1468 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001469 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001470 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471 EXPECT_EQ(111, gcodec.pltype);
1472 EXPECT_EQ(96000, gcodec.rate);
1473 EXPECT_STREQ("opus", gcodec.plname);
1474 EXPECT_EQ(1, gcodec.channels);
1475 EXPECT_EQ(48000, gcodec.plfreq);
1476}
1477
1478// Test that with bitrate=N and stereo=0,
1479// channels and bitrate are 1 and N.
1480TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001481 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001482 cricket::AudioSendParameters parameters;
1483 parameters.codecs.push_back(kOpusCodec);
1484 parameters.codecs[0].bitrate = 30000;
1485 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001487 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
1490// Test that with bitrate=N and without any parameters,
1491// channels and bitrate are 1 and N.
1492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001493 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001494 cricket::AudioSendParameters parameters;
1495 parameters.codecs.push_back(kOpusCodec);
1496 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001497 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001498 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499}
1500
1501// Test that with bitrate=N and stereo=1,
1502// channels and bitrate are 2 and N.
1503TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001504 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001505 cricket::AudioSendParameters parameters;
1506 parameters.codecs.push_back(kOpusCodec);
1507 parameters.codecs[0].bitrate = 30000;
1508 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001509 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001510 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511}
1512
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001513// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1514// Also test that the "maxaveragebitrate" can't be set to values outside the
1515// range of 6000 and 510000
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001517 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 cricket::AudioSendParameters parameters;
1519 parameters.codecs.push_back(kOpusCodec);
1520 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001521 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001522 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001523 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001524 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001525
1526 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001528 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001529 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001530
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001531 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001532 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001533 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001534}
1535
stefan13f1a0a2016-11-30 07:22:58 -08001536TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1537 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1538 200000);
1539}
1540
1541TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1542 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1543}
1544
1545TEST_F(WebRtcVoiceEngineTestFake,
1546 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1547 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1548}
1549
1550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1551 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1552}
1553
1554TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001555 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001556 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1557 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001558 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001559 SetSendParameters(send_parameters_);
1560 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1561 << "Setting max bitrate should keep previous min bitrate.";
1562 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1563 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001564 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001565}
1566
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001567// Test that we can enable NACK with opus as caller.
1568TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001569 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001570 cricket::AudioSendParameters parameters;
1571 parameters.codecs.push_back(kOpusCodec);
1572 parameters.codecs[0].AddFeedbackParam(
1573 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1574 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001575 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578}
1579
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001580// Test that we can enable NACK with opus as callee.
1581TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001582 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001583 cricket::AudioSendParameters parameters;
1584 parameters.codecs.push_back(kOpusCodec);
1585 parameters.codecs[0].AddFeedbackParam(
1586 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1587 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001589 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001590 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001591 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001592
1593 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001594 cricket::StreamParams::CreateLegacy(kSsrcX)));
1595 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001596}
1597
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598// Test that we can enable NACK on receive streams.
1599TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001600 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001602 cricket::AudioSendParameters parameters;
1603 parameters.codecs.push_back(kOpusCodec);
1604 parameters.codecs[0].AddFeedbackParam(
1605 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1606 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001607 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1608 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001609 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001610 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1611 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612}
1613
1614// Test that we can disable NACK.
1615TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
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(kOpusCodec);
1619 parameters.codecs[0].AddFeedbackParam(
1620 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1621 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001622 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001623 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 parameters.codecs.clear();
1626 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001627 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001628 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001629}
1630
1631// Test that we can disable NACK on receive streams.
1632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001633 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001634 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kOpusCodec);
1637 parameters.codecs[0].AddFeedbackParam(
1638 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1639 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001640 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001641 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1642 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 parameters.codecs.clear();
1645 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001646 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001647 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1648 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001649}
1650
1651// Test that NACK is enabled on a new receive stream.
1652TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001653 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 cricket::AudioSendParameters parameters;
1655 parameters.codecs.push_back(kIsacCodec);
1656 parameters.codecs.push_back(kCn16000Codec);
1657 parameters.codecs[0].AddFeedbackParam(
1658 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1659 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001660 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001661 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662
solenberg2100c0b2017-03-01 11:29:29 -08001663 EXPECT_TRUE(AddRecvStream(kSsrcY));
1664 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1665 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1666 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667}
1668
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001669// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001670TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001671 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 cricket::AudioSendParameters parameters;
1673 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001674 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001675 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001676}
1677
1678// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001679TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001680 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 cricket::AudioSendParameters parameters;
1682 parameters.codecs.push_back(kOpusCodec);
1683 parameters.codecs[0].bitrate = 0;
1684 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001685 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001686 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001687}
1688
1689// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001690TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001691 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001692 cricket::AudioSendParameters parameters;
1693 parameters.codecs.push_back(kOpusCodec);
1694 parameters.codecs[0].bitrate = 0;
1695 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_TRUE(GetCodecFec(kSsrcX));
1698 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001699}
1700
1701// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001702TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001703 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001704 cricket::AudioSendParameters parameters;
1705 parameters.codecs.push_back(kOpusCodec);
1706 parameters.codecs[0].bitrate = 0;
1707 parameters.codecs[0].params["stereo"] = "1";
1708 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001710 EXPECT_TRUE(GetCodecFec(kSsrcX));
1711 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001712}
1713
1714// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001715TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001716 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001717 cricket::AudioSendParameters parameters;
1718 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001719 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001720 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001721}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001722
1723// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1724TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001725 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001726 cricket::AudioSendParameters parameters;
1727 parameters.codecs.push_back(kIsacCodec);
1728 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001730 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001731}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001732
1733// Test that Opus FEC status can be changed.
1734TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001735 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001736 cricket::AudioSendParameters parameters;
1737 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001738 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001739 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001740
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001741 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001742 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001743 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001744}
1745
stefanba4c0e42016-02-04 04:12:24 -08001746TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001747 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001748 cricket::AudioSendParameters send_parameters;
1749 send_parameters.codecs.push_back(kOpusCodec);
1750 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001751 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001752
1753 cricket::AudioRecvParameters recv_parameters;
1754 recv_parameters.codecs.push_back(kIsacCodec);
1755 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001756 EXPECT_TRUE(AddRecvStream(kSsrcX));
1757 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001758 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001759 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001760
ossudedfd282016-06-14 07:12:39 -07001761 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001762 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001763 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001764 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001765 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001766}
1767
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001768// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1769TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001770 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001771 cricket::AudioSendParameters parameters;
1772 parameters.codecs.push_back(kOpusCodec);
1773 parameters.codecs[0].bitrate = 0;
1774 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001775 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001776 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1777 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001778
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001780 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001781 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001782}
1783
1784// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1785TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
solenbergff976312016-03-30 23:28:51 -07001786 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 cricket::AudioSendParameters parameters;
1788 parameters.codecs.push_back(kOpusCodec);
1789 parameters.codecs[0].bitrate = 0;
1790 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001791 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001792 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1793 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001794
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001795 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001796 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001797 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001798}
1799
1800// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1801TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
solenbergff976312016-03-30 23:28:51 -07001802 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001803 cricket::AudioSendParameters parameters;
1804 parameters.codecs.push_back(kOpusCodec);
1805 parameters.codecs[0].bitrate = 0;
1806 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001808 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1809 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001810
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001812 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001813 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001814}
1815
1816// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1817TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001818 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001819 cricket::AudioSendParameters parameters;
1820 parameters.codecs.push_back(kOpusCodec);
1821 parameters.codecs[0].bitrate = 0;
1822 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001823 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001824 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1825 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001826
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001827 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001828 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001829 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001830}
1831
1832// Test 24000 < maxplaybackrate triggers Opus full band mode.
1833TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001834 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001835 cricket::AudioSendParameters parameters;
1836 parameters.codecs.push_back(kOpusCodec);
1837 parameters.codecs[0].bitrate = 0;
1838 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001839 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001840 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1841 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001842
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001843 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001844 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001845 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001846}
1847
1848// Test Opus that without maxplaybackrate, default playback rate is used.
1849TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001850 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001851 cricket::AudioSendParameters parameters;
1852 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001854 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001855}
1856
1857// Test the with non-Opus, maxplaybackrate has no effect.
1858TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001859 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 cricket::AudioSendParameters parameters;
1861 parameters.codecs.push_back(kIsacCodec);
1862 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001863 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001864 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001865}
1866
1867// Test maxplaybackrate can be set on two streams.
1868TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001869 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001870 cricket::AudioSendParameters parameters;
1871 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001872 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001873 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001874
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001875 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001876 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001877 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001878
solenberg2100c0b2017-03-01 11:29:29 -08001879 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1880 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001881}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001882
Minyue Li7100dcd2015-03-27 05:05:59 +01001883// Test that with usedtx=0, Opus DTX is off.
1884TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001885 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001886 cricket::AudioSendParameters parameters;
1887 parameters.codecs.push_back(kOpusCodec);
1888 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001889 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001890 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001891}
1892
1893// Test that with usedtx=1, Opus DTX is on.
1894TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001895 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001896 cricket::AudioSendParameters parameters;
1897 parameters.codecs.push_back(kOpusCodec);
1898 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001899 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001900 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001901}
1902
1903// Test that usedtx=1 works with stereo Opus.
1904TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001905 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001906 cricket::AudioSendParameters parameters;
1907 parameters.codecs.push_back(kOpusCodec);
1908 parameters.codecs[0].params["usedtx"] = "1";
1909 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001910 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001911 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001912}
1913
1914// Test that usedtx=1 does not work with non Opus.
1915TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001916 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001917 cricket::AudioSendParameters parameters;
1918 parameters.codecs.push_back(kIsacCodec);
1919 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001920 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001921 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001922}
1923
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001924// Test that we can switch back and forth between Opus and ISAC with CN.
1925TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001926 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001927
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 cricket::AudioSendParameters opus_parameters;
1929 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001930 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001931 {
solenberg2100c0b2017-03-01 11:29:29 -08001932 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001933 EXPECT_EQ(111, gcodec.pltype);
1934 EXPECT_STREQ("opus", gcodec.plname);
1935 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001936
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001937 cricket::AudioSendParameters isac_parameters;
1938 isac_parameters.codecs.push_back(kIsacCodec);
1939 isac_parameters.codecs.push_back(kCn16000Codec);
1940 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(isac_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 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001947
solenberg059fb442016-10-26 05:12:24 -07001948 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001949 {
solenberg2100c0b2017-03-01 11:29:29 -08001950 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001951 EXPECT_EQ(111, gcodec.pltype);
1952 EXPECT_STREQ("opus", gcodec.plname);
1953 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001954}
1955
1956// Test that we handle various ways of specifying bitrate.
1957TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001958 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001959 cricket::AudioSendParameters parameters;
1960 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001961 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001962 {
solenberg2100c0b2017-03-01 11:29:29 -08001963 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001964 EXPECT_EQ(103, gcodec.pltype);
1965 EXPECT_STREQ("ISAC", gcodec.plname);
1966 EXPECT_EQ(32000, gcodec.rate);
1967 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001969 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001970 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001971 {
solenberg2100c0b2017-03-01 11:29:29 -08001972 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001973 EXPECT_EQ(103, gcodec.pltype);
1974 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001975 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001976 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001977 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001978 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001979 {
solenberg2100c0b2017-03-01 11:29:29 -08001980 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001981 EXPECT_EQ(103, gcodec.pltype);
1982 EXPECT_STREQ("ISAC", gcodec.plname);
1983 EXPECT_EQ(28000, gcodec.rate);
1984 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001985
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001986 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001987 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001988 {
solenberg2100c0b2017-03-01 11:29:29 -08001989 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001990 EXPECT_EQ(0, gcodec.pltype);
1991 EXPECT_STREQ("PCMU", gcodec.plname);
1992 EXPECT_EQ(64000, gcodec.rate);
1993 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001994
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001995 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001996 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001997 {
solenberg2100c0b2017-03-01 11:29:29 -08001998 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001999 EXPECT_EQ(0, gcodec.pltype);
2000 EXPECT_STREQ("PCMU", gcodec.plname);
2001 EXPECT_EQ(64000, gcodec.rate);
2002 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002003
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002004 parameters.codecs[0] = kOpusCodec;
2005 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07002006 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002007 {
solenberg2100c0b2017-03-01 11:29:29 -08002008 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07002009 EXPECT_EQ(111, gcodec.pltype);
2010 EXPECT_STREQ("opus", gcodec.plname);
2011 EXPECT_EQ(32000, gcodec.rate);
2012 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002013}
2014
Brave Yao5225dd82015-03-26 07:39:19 +08002015// Test that we could set packet size specified in kCodecParamPTime.
2016TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07002017 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002018 cricket::AudioSendParameters parameters;
2019 parameters.codecs.push_back(kOpusCodec);
2020 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002021 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002022 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002023
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002024 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07002025 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002026 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002027
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002028 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07002029 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002030 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08002031
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002032 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
2033 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07002034 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002035 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002036 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08002037
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002038 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
2039 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07002040 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002041 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08002042 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08002043}
2044
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002045// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002046TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002047 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002048 cricket::AudioSendParameters parameters;
2049 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002050}
2051
2052// Test that we can set send codecs even with telephone-event codec as the first
2053// one on the list.
2054TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002055 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002056 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002057 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002058 parameters.codecs.push_back(kIsacCodec);
2059 parameters.codecs.push_back(kPcmuCodec);
2060 parameters.codecs[0].id = 98; // DTMF
2061 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002062 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002063 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002064 EXPECT_EQ(96, gcodec.pltype);
2065 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002066 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002067}
2068
solenberg31642aa2016-03-14 08:00:37 -07002069// Test that payload type range is limited for telephone-event codec.
2070TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002071 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002072 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002073 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002074 parameters.codecs.push_back(kIsacCodec);
2075 parameters.codecs[0].id = 0; // DTMF
2076 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002077 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002078 EXPECT_TRUE(channel_->CanInsertDtmf());
2079 parameters.codecs[0].id = 128; // DTMF
2080 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2081 EXPECT_FALSE(channel_->CanInsertDtmf());
2082 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002083 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002084 EXPECT_TRUE(channel_->CanInsertDtmf());
2085 parameters.codecs[0].id = -1; // DTMF
2086 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2087 EXPECT_FALSE(channel_->CanInsertDtmf());
2088}
2089
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002090// Test that we can set send codecs even with CN codec as the first
2091// one on the list.
2092TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002093 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002094 cricket::AudioSendParameters parameters;
2095 parameters.codecs.push_back(kCn16000Codec);
2096 parameters.codecs.push_back(kIsacCodec);
2097 parameters.codecs.push_back(kPcmuCodec);
2098 parameters.codecs[0].id = 98; // wideband CN
2099 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002100 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002101 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002102 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2103 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2104 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2105 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002106}
2107
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002108// Test that we set VAD and DTMF types correctly as caller.
2109TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002110 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002111 cricket::AudioSendParameters parameters;
2112 parameters.codecs.push_back(kIsacCodec);
2113 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002114 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002115 parameters.codecs.push_back(kCn16000Codec);
2116 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002117 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002118 parameters.codecs[0].id = 96;
2119 parameters.codecs[2].id = 97; // wideband CN
2120 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002121 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002122 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002123 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2124 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2125 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2126 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2127 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2128 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002129 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130}
2131
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002132// Test that we set VAD and DTMF types correctly as callee.
2133TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002134 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002135 cricket::AudioSendParameters parameters;
2136 parameters.codecs.push_back(kIsacCodec);
2137 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002138 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002139 parameters.codecs.push_back(kCn16000Codec);
2140 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002141 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002142 parameters.codecs[0].id = 96;
2143 parameters.codecs[2].id = 97; // wideband CN
2144 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002145 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002146 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002147 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002148
solenberg2100c0b2017-03-01 11:29:29 -08002149 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002150 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2151 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2152 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2153 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2154 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2155 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002156 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002157}
2158
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002159// Test that we only apply VAD if we have a CN codec that matches the
2160// send codec clockrate.
2161TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002162 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002163 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002164 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002165 parameters.codecs.push_back(kIsacCodec);
2166 parameters.codecs.push_back(kCn16000Codec);
2167 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002168 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002169 {
solenberg2100c0b2017-03-01 11:29:29 -08002170 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002171 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2172 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2173 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2174 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2175 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2176 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002178 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002179 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002180 {
solenberg2100c0b2017-03-01 11:29:29 -08002181 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002182 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2183 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2184 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002186 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002187 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002188 {
solenberg2100c0b2017-03-01 11:29:29 -08002189 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002190 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2191 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2192 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2193 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2194 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2195 }
Brave Yao5225dd82015-03-26 07:39:19 +08002196 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002197 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002198 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002199 {
solenberg2100c0b2017-03-01 11:29:29 -08002200 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002201 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2202 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2203 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204}
2205
2206// Test that we perform case-insensitive matching of codec names.
2207TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002208 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002209 cricket::AudioSendParameters parameters;
2210 parameters.codecs.push_back(kIsacCodec);
2211 parameters.codecs.push_back(kPcmuCodec);
2212 parameters.codecs.push_back(kCn16000Codec);
2213 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002214 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002215 parameters.codecs[0].name = "iSaC";
2216 parameters.codecs[0].id = 96;
2217 parameters.codecs[2].id = 97; // wideband CN
2218 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002219 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002220 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002221 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2222 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2223 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2224 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2225 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2226 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002227 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002228}
2229
stefanba4c0e42016-02-04 04:12:24 -08002230class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2231 public:
2232 WebRtcVoiceEngineWithSendSideBweTest()
2233 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2234};
2235
2236TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2237 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002238 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002239 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002240 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2241 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2242 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002243 extension.id);
2244 return;
2245 }
2246 }
2247 FAIL() << "Transport sequence number extension not in header-extension list.";
2248}
2249
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002250// Test support for audio level header extension.
2251TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002252 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002253}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002254TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002255 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002256}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002257
solenbergd4adce42016-11-17 06:26:52 -08002258// Test support for transport sequence number header extension.
2259TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2260 TestSetSendRtpHeaderExtensions(
2261 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002262}
solenbergd4adce42016-11-17 06:26:52 -08002263TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2264 TestSetRecvRtpHeaderExtensions(
2265 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002266}
2267
solenberg1ac56142015-10-13 03:58:19 -07002268// Test that we can create a channel and start sending on it.
2269TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002270 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002271 SetSendParameters(send_parameters_);
2272 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002273 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002274 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002275 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002276}
2277
2278// Test that a channel will send if and only if it has a source and is enabled
2279// for sending.
2280TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002281 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002282 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002283 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002284 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002285 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2286 SetAudioSend(kSsrcX, true, &fake_source_);
2287 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2288 SetAudioSend(kSsrcX, true, nullptr);
2289 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002290}
2291
solenberg94218532016-06-16 10:53:22 -07002292// Test that a channel is muted/unmuted.
2293TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2294 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002295 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002296 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2297 SetAudioSend(kSsrcX, true, nullptr);
2298 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2299 SetAudioSend(kSsrcX, false, nullptr);
2300 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002301}
2302
solenberg6d6e7c52016-04-13 09:07:30 -07002303// Test that SetSendParameters() does not alter a stream's send state.
2304TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2305 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002306 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002307
2308 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002309 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002310 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002311
2312 // Changing RTP header extensions will recreate the AudioSendStream.
2313 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002314 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002315 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002317
2318 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002319 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002320 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002321
2322 // Changing RTP header extensions will recreate the AudioSendStream.
2323 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002324 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002325 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002326}
2327
solenberg1ac56142015-10-13 03:58:19 -07002328// Test that we can create a channel and start playing out on it.
2329TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002330 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002331 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002332 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002333 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002334 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002335 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002336}
2337
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002338// Test that we can add and remove send streams.
2339TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2340 SetupForMultiSendStream();
2341
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002342 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002343 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002344
solenbergc96df772015-10-21 13:01:53 -07002345 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002346 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002347 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002348 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002349 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002350 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002351 }
tfarina5237aaf2015-11-10 23:44:30 -08002352 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002353
solenbergc96df772015-10-21 13:01:53 -07002354 // Delete the send streams.
2355 for (uint32_t ssrc : kSsrcs4) {
2356 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002357 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002358 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002359 }
solenbergc96df772015-10-21 13:01:53 -07002360 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002361}
2362
2363// Test SetSendCodecs correctly configure the codecs in all send streams.
2364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2365 SetupForMultiSendStream();
2366
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002367 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002368 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002369 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002370 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002371 }
2372
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002373 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002374 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002375 parameters.codecs.push_back(kIsacCodec);
2376 parameters.codecs.push_back(kCn16000Codec);
2377 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002378 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002379
2380 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002381 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002382 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2383 const auto& send_codec_spec =
2384 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2385 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2386 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2387 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2388 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2389 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002390 }
2391
minyue7a973442016-10-20 03:27:12 -07002392 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002393 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002394 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002395 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002396 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2397 const auto& send_codec_spec =
2398 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2399 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002400 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002401 }
2402}
2403
2404// Test we can SetSend on all send streams correctly.
2405TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2406 SetupForMultiSendStream();
2407
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002408 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002409 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002410 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002411 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002412 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002413 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002414 }
2415
2416 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002417 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002418 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002419 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002420 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002421 }
2422
2423 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002424 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002425 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002426 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002427 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002428 }
2429}
2430
2431// Test we can set the correct statistics on all send streams.
2432TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2433 SetupForMultiSendStream();
2434
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002435 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002436 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002437 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002438 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002439 }
solenberg85a04962015-10-27 03:35:21 -07002440
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002441 // Create a receive stream to check that none of the send streams end up in
2442 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002443 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002444
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002445 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002446 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002447 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002448 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002449
solenberg85a04962015-10-27 03:35:21 -07002450 // Check stats for the added streams.
2451 {
2452 cricket::VoiceMediaInfo info;
2453 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002454
solenberg85a04962015-10-27 03:35:21 -07002455 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002456 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002457 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002458 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002459 }
hbos1acfbd22016-11-17 23:43:29 -08002460 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002461
2462 // We have added one receive stream. We should see empty stats.
2463 EXPECT_EQ(info.receivers.size(), 1u);
2464 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002465 }
solenberg1ac56142015-10-13 03:58:19 -07002466
solenberg2100c0b2017-03-01 11:29:29 -08002467 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002468 {
2469 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002470 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002471 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002472 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002473 EXPECT_EQ(0u, info.receivers.size());
2474 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002475
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002476 // Deliver a new packet - a default receive stream should be created and we
2477 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002478 {
2479 cricket::VoiceMediaInfo info;
2480 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2481 SetAudioReceiveStreamStats();
2482 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002483 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002484 EXPECT_EQ(1u, info.receivers.size());
2485 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002486 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002487 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002488}
2489
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002490// Test that we can add and remove receive streams, and do proper send/playout.
2491// We can receive on multiple streams while sending one stream.
2492TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002493 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494
solenberg1ac56142015-10-13 03:58:19 -07002495 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002496 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002497 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002498
solenberg1ac56142015-10-13 03:58:19 -07002499 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002500 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002501 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002502 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002503
solenberg1ac56142015-10-13 03:58:19 -07002504 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002505 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506
2507 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002508 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2509 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2510 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511
2512 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002513 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002514 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002515
2516 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002517 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002518 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2519 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520
aleloi84ef6152016-08-04 05:28:21 -07002521 // Restart playout and make sure recv streams are played out.
2522 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002523 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2524 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002525
aleloi84ef6152016-08-04 05:28:21 -07002526 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002527 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2528 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529}
2530
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002532// and start sending on it.
2533TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002534 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002535 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2536 EXPECT_CALL(apm_gc_,
2537 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002538 SetSendParameters(send_parameters_);
2539 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002540 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002541 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002542 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543}
2544
wu@webrtc.org97077a32013-10-25 21:18:33 +00002545TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002546 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002547 EXPECT_CALL(adm_,
2548 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002549 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2550 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002551 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2552 send_parameters_.options.tx_agc_digital_compression_gain =
2553 rtc::Optional<uint16_t>(9);
2554 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2555 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002556 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2557 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2558 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002559 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002560
2561 // Check interaction with adjust_agc_delta. Both should be respected, for
2562 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002563 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002564 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002565 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002566}
2567
wu@webrtc.org97077a32013-10-25 21:18:33 +00002568TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002569 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002570 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2571 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002572 send_parameters_.options.recording_sample_rate =
2573 rtc::Optional<uint32_t>(48000);
2574 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002575 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002576}
2577
minyue6b825df2016-10-31 04:08:32 -07002578TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2579 EXPECT_TRUE(SetupSendStream());
2580 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2581 send_parameters_.options.audio_network_adaptor_config =
2582 rtc::Optional<std::string>("1234");
2583 SetSendParameters(send_parameters_);
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
2588TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2589 EXPECT_TRUE(SetupSendStream());
2590 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2591 send_parameters_.options.audio_network_adaptor_config =
2592 rtc::Optional<std::string>("1234");
2593 SetSendParameters(send_parameters_);
2594 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002595 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002596 const int initial_num = call_.GetNumCreatedSendStreams();
2597 cricket::AudioOptions options;
2598 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002599 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002600 // AudioSendStream expected to be recreated.
2601 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002602 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002603}
2604
2605TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2606 EXPECT_TRUE(SetupSendStream());
2607 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2608 send_parameters_.options.audio_network_adaptor_config =
2609 rtc::Optional<std::string>("1234");
2610 SetSendParameters(send_parameters_);
2611 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002612 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002613 const int initial_num = call_.GetNumCreatedSendStreams();
2614 cricket::AudioOptions options;
2615 options.audio_network_adaptor = rtc::Optional<bool>();
2616 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2617 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002618 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002619 // AudioSendStream not expected to be recreated.
2620 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2621 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002622 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002623}
2624
michaelt6672b262017-01-11 10:17:59 -08002625class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2626 : public WebRtcVoiceEngineTestFake {
2627 public:
2628 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2629 : WebRtcVoiceEngineTestFake(
2630 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2631 "Enabled/") {}
2632};
2633
2634TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2635 EXPECT_TRUE(SetupSendStream());
2636 cricket::AudioSendParameters parameters;
2637 parameters.codecs.push_back(kOpusCodec);
2638 SetSendParameters(parameters);
2639 const int initial_num = call_.GetNumCreatedSendStreams();
2640 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2641
2642 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2643 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002644 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2645 constexpr int kMinOverheadBps =
2646 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002647
2648 constexpr int kOpusMinBitrateBps = 6000;
2649 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002650 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002651 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002652 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002653 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002654
2655 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2656 parameters.options.audio_network_adaptor_config =
2657 rtc::Optional<std::string>("1234");
2658 SetSendParameters(parameters);
2659
ossu11bfc532017-02-16 05:37:06 -08002660 constexpr int kMinOverheadWithAnaBps =
2661 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002662
2663 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002664 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002665
minyuececec102017-03-27 13:04:25 -07002666 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002667 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002668}
2669
minyuececec102017-03-27 13:04:25 -07002670// This test is similar to
2671// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2672// additional field trial.
2673TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2674 SetRtpSendParameterUpdatesMaxBitrate) {
2675 EXPECT_TRUE(SetupSendStream());
2676 cricket::AudioSendParameters send_parameters;
2677 send_parameters.codecs.push_back(kOpusCodec);
2678 SetSendParameters(send_parameters);
2679
2680 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2681 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2682 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2683
2684 constexpr int kMaxBitrateBps = 6000;
2685 rtp_parameters.encodings[0].max_bitrate_bps =
2686 rtc::Optional<int>(kMaxBitrateBps);
2687 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2688
2689 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2690#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2691 constexpr int kMinOverhead = 3333;
2692#else
2693 constexpr int kMinOverhead = 6666;
2694#endif
2695 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2696}
2697
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002698// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002699// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002700TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002701 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002702 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703}
2704
2705TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2706 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002707 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002708 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002709 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002710 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002711 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002712 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002713 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714
solenberg85a04962015-10-27 03:35:21 -07002715 // Check stats for the added streams.
2716 {
2717 cricket::VoiceMediaInfo info;
2718 EXPECT_EQ(true, channel_->GetStats(&info));
2719
2720 // We have added one send stream. We should see the stats we've set.
2721 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002722 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002723 // We have added one receive stream. We should see empty stats.
2724 EXPECT_EQ(info.receivers.size(), 1u);
2725 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2726 }
solenberg1ac56142015-10-13 03:58:19 -07002727
solenberg566ef242015-11-06 15:34:49 -08002728 // Start sending - this affects some reported stats.
2729 {
2730 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002731 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002732 EXPECT_EQ(true, channel_->GetStats(&info));
2733 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002734 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002735 }
2736
solenberg2100c0b2017-03-01 11:29:29 -08002737 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002738 {
2739 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002740 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002741 EXPECT_EQ(true, channel_->GetStats(&info));
2742 EXPECT_EQ(1u, info.senders.size());
2743 EXPECT_EQ(0u, info.receivers.size());
2744 }
solenberg1ac56142015-10-13 03:58:19 -07002745
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002746 // Deliver a new packet - a default receive stream should be created and we
2747 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002748 {
2749 cricket::VoiceMediaInfo info;
2750 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2751 SetAudioReceiveStreamStats();
2752 EXPECT_EQ(true, channel_->GetStats(&info));
2753 EXPECT_EQ(1u, info.senders.size());
2754 EXPECT_EQ(1u, info.receivers.size());
2755 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002756 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002757 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758}
2759
2760// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002761// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002763 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002764 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2765 EXPECT_TRUE(AddRecvStream(kSsrcY));
2766 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002767}
2768
2769// Test that the local SSRC is the same on sending and receiving channels if the
2770// receive channel is created before the send channel.
2771TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002773 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002775 cricket::StreamParams::CreateLegacy(kSsrcX)));
2776 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2777 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002778}
2779
2780// Test that we can properly receive packets.
2781TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002782 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002783 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002784 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002785
2786 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2787 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002788}
2789
2790// Test that we can properly receive packets on multiple streams.
2791TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002792 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002793 const uint32_t ssrc1 = 1;
2794 const uint32_t ssrc2 = 2;
2795 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002796 EXPECT_TRUE(AddRecvStream(ssrc1));
2797 EXPECT_TRUE(AddRecvStream(ssrc2));
2798 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002799 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002800 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002801 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002802 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002803 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804 }
mflodman3d7db262016-04-29 00:57:13 -07002805
2806 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2807 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2808 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2809
2810 EXPECT_EQ(s1.received_packets(), 0);
2811 EXPECT_EQ(s2.received_packets(), 0);
2812 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002813
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002814 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002815 EXPECT_EQ(s1.received_packets(), 0);
2816 EXPECT_EQ(s2.received_packets(), 0);
2817 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002818
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002819 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002820 EXPECT_EQ(s1.received_packets(), 1);
2821 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2822 EXPECT_EQ(s2.received_packets(), 0);
2823 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002824
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002826 EXPECT_EQ(s1.received_packets(), 1);
2827 EXPECT_EQ(s2.received_packets(), 1);
2828 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2829 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002830
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002832 EXPECT_EQ(s1.received_packets(), 1);
2833 EXPECT_EQ(s2.received_packets(), 1);
2834 EXPECT_EQ(s3.received_packets(), 1);
2835 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002836
mflodman3d7db262016-04-29 00:57:13 -07002837 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2838 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2839 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840}
2841
solenberg2100c0b2017-03-01 11:29:29 -08002842// Test that receiving on an unsignaled stream works (a stream is created).
2843TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002844 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002845 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2846
solenberg7e63ef02015-11-20 00:19:43 -08002847 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002848
2849 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002850 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2851 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002852}
2853
solenberg2100c0b2017-03-01 11:29:29 -08002854// Test that receiving N unsignaled stream works (streams will be created), and
2855// that packets are forwarded to them all.
2856TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002857 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002858 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002859 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2860
solenberg2100c0b2017-03-01 11:29:29 -08002861 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002862 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002863 rtc::SetBE32(&packet[8], ssrc);
2864 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002865
solenberg2100c0b2017-03-01 11:29:29 -08002866 // Verify we have one new stream for each loop iteration.
2867 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002868 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2869 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002870 }
mflodman3d7db262016-04-29 00:57:13 -07002871
solenberg2100c0b2017-03-01 11:29:29 -08002872 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002873 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002874 rtc::SetBE32(&packet[8], ssrc);
2875 DeliverPacket(packet, sizeof(packet));
2876
solenbergebb349d2017-03-13 05:46:15 -07002877 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002878 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2879 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2880 }
2881
2882 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2883 constexpr uint32_t kAnotherSsrc = 667;
2884 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002885 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002886
2887 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002888 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002889 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002890 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002891 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2892 EXPECT_EQ(2, streams[i]->received_packets());
2893 }
2894 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2895 EXPECT_EQ(1, streams[i]->received_packets());
2896 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002897 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002898}
2899
solenberg2100c0b2017-03-01 11:29:29 -08002900// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002901// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002902TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002903 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002904 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002905 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2906
2907 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002908 const uint32_t signaled_ssrc = 1;
2909 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002910 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002911 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002912 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2913 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002914 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002915
2916 // Note that the first unknown SSRC cannot be 0, because we only support
2917 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002918 const uint32_t unsignaled_ssrc = 7011;
2919 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002920 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002921 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2922 packet, sizeof(packet)));
2923 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2924
2925 DeliverPacket(packet, sizeof(packet));
2926 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2927
2928 rtc::SetBE32(&packet[8], signaled_ssrc);
2929 DeliverPacket(packet, sizeof(packet));
2930 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2931 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002932}
2933
solenberg4904fb62017-02-17 12:01:14 -08002934// Two tests to verify that adding a receive stream with the same SSRC as a
2935// previously added unsignaled stream will only recreate underlying stream
2936// objects if the stream parameters have changed.
2937TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2938 EXPECT_TRUE(SetupChannel());
2939
2940 // Spawn unsignaled stream with SSRC=1.
2941 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2942 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2943 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2944 sizeof(kPcmuFrame)));
2945
2946 // Verify that the underlying stream object in Call is not recreated when a
2947 // stream with SSRC=1 is added.
2948 const auto& streams = call_.GetAudioReceiveStreams();
2949 EXPECT_EQ(1, streams.size());
2950 int audio_receive_stream_id = streams.front()->id();
2951 EXPECT_TRUE(AddRecvStream(1));
2952 EXPECT_EQ(1, streams.size());
2953 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2954}
2955
2956TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2957 EXPECT_TRUE(SetupChannel());
2958
2959 // Spawn unsignaled stream with SSRC=1.
2960 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2961 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2962 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2963 sizeof(kPcmuFrame)));
2964
2965 // Verify that the underlying stream object in Call *is* recreated when a
2966 // stream with SSRC=1 is added, and which has changed stream parameters.
2967 const auto& streams = call_.GetAudioReceiveStreams();
2968 EXPECT_EQ(1, streams.size());
2969 int audio_receive_stream_id = streams.front()->id();
2970 cricket::StreamParams stream_params;
2971 stream_params.ssrcs.push_back(1);
2972 stream_params.sync_label = "sync_label";
2973 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2974 EXPECT_EQ(1, streams.size());
2975 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2976}
2977
solenberg0a617e22015-10-20 15:49:38 -07002978// Test that we properly handle failures to add a receive stream.
2979TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002980 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002981 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002982 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002983}
2984
solenberg0a617e22015-10-20 15:49:38 -07002985// Test that we properly handle failures to add a send stream.
2986TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002987 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002988 voe_.set_fail_create_channel(true);
2989 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2990}
2991
solenberg1ac56142015-10-13 03:58:19 -07002992// Test that AddRecvStream creates new stream.
2993TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002994 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002996 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002997 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998}
2999
3000// Test that after adding a recv stream, we do not decode more codecs than
3001// those previously passed into SetRecvCodecs.
3002TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07003003 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003004 cricket::AudioRecvParameters parameters;
3005 parameters.codecs.push_back(kIsacCodec);
3006 parameters.codecs.push_back(kPcmuCodec);
3007 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08003008 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07003009 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
3010 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
3011 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003012}
3013
3014// Test that we properly clean up any streams that were added, even if
3015// not explicitly removed.
3016TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07003017 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003018 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07003019 EXPECT_TRUE(AddRecvStream(1));
3020 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
3022 delete channel_;
3023 channel_ = NULL;
3024 EXPECT_EQ(0, voe_.GetNumChannels());
3025}
3026
wu@webrtc.org78187522013-10-07 23:32:02 +00003027TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07003028 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07003029 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00003030}
3031
3032TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07003033 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07003034 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07003035 // Manually delete channel to simulate a failure.
3036 int channel = voe_.GetLastChannel();
3037 EXPECT_EQ(0, voe_.DeleteChannel(channel));
3038 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07003039 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00003040 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07003041 EXPECT_NE(channel, new_channel);
3042 // The last created channel is deleted too.
3043 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00003044}
3045
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003046// Test the InsertDtmf on default send stream as caller.
3047TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08003048 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003049}
3050
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003051// Test the InsertDtmf on default send stream as callee
3052TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08003053 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003054}
3055
3056// Test the InsertDtmf on specified send stream as caller.
3057TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08003058 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00003059}
3060
3061// Test the InsertDtmf on specified send stream as callee.
3062TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08003063 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003064}
3065
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07003067 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003068 EXPECT_CALL(adm_,
3069 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3070 EXPECT_CALL(adm_,
3071 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3072 EXPECT_CALL(adm_,
3073 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003074
solenberg246b8172015-12-08 09:50:23 -08003075 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3076 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077
solenberg246b8172015-12-08 09:50:23 -08003078 // Nothing set in AudioOptions, so everything should be as default.
3079 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003080 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003081 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003082 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3083 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003084
3085 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003086 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003088 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003089 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003090
3091 // Turn echo cancellation back on, with settings, and make sure
3092 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003093 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3094 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003095 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003096 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003097
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003098 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3099 // control.
solenberg76377c52017-02-21 00:54:31 -08003100 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3101 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003102 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003103 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003104
3105 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003106 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3107 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003108 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3109 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3110 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003111 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003112
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003113 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003114 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3115 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003116 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003117 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003118
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003119 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003120 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3121 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3122 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3123 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003124 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003125 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003126
3127 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003128 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3129 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3130 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3131 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003132 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3133 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003134 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003135
3136 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003137 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3138 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3139 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3140 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3141 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3142 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3143 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003144 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3145 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3146 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3147 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003148 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003149 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003150
solenberg1ac56142015-10-13 03:58:19 -07003151 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003152 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3153 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3154 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3155 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3156 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3157 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3158 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003159 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003160}
3161
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003162TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003163 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003164 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003165 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003166 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003167 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003168 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003169 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003170 EXPECT_CALL(adm_,
3171 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3172 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3173 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3174 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3175 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003176
kwiberg686a8ef2016-02-26 03:00:35 -08003177 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003178 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003179 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003180 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003181 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003182 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183
3184 // Have to add a stream to make SetSend work.
3185 cricket::StreamParams stream1;
3186 stream1.ssrcs.push_back(1);
3187 channel1->AddSendStream(stream1);
3188 cricket::StreamParams stream2;
3189 stream2.ssrcs.push_back(2);
3190 channel2->AddSendStream(stream2);
3191
3192 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003193 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003194 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3195 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3196 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003197 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3198 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3199 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3200 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3201 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003202 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003203 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003204 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003205 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003206
3207 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003208 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003209 parameters_options_no_ns.options.noise_suppression =
3210 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003211 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3212 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3213 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3214 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3215 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003216 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003217 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003218 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3219 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3220 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003221 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003222
3223 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003224 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003225 parameters_options_no_agc.options.auto_gain_control =
3226 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003227 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3228 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3229 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3230 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3231 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003232 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003233 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3234 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3235 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003236 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003237
solenberg76377c52017-02-21 00:54:31 -08003238 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3239 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3240 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3241 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3242 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003243 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003244
solenberg76377c52017-02-21 00:54:31 -08003245 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3246 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3247 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3248 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3249 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003250 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003251
solenberg76377c52017-02-21 00:54:31 -08003252 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3253 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3254 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3255 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3256 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003257 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003258
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003259 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003260 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3261 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003262 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003263 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003264 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003265 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003266 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3267 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3268 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3269 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3270 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003271 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003272 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3273 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3274 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003275 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003276}
3277
wu@webrtc.orgde305012013-10-31 15:40:38 +00003278// This test verifies DSCP settings are properly applied on voice media channel.
3279TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003280 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003281 cricket::FakeNetworkInterface network_interface;
3282 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003283 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003284
solenberg059fb442016-10-26 05:12:24 -07003285 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3286 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3287
solenbergbc37fc82016-04-04 09:54:44 -07003288 channel.reset(
3289 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003290 channel->SetInterface(&network_interface);
3291 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3292 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3293
3294 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003295 channel.reset(
3296 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003297 channel->SetInterface(&network_interface);
3298 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3299
3300 // Verify that setting the option to false resets the
3301 // DiffServCodePoint.
3302 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003303 channel.reset(
3304 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003305 channel->SetInterface(&network_interface);
3306 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3307 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3308
3309 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003310}
3311
solenberg1ac56142015-10-13 03:58:19 -07003312TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003313 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003314 cricket::WebRtcVoiceMediaChannel* media_channel =
3315 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003316 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003317 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003318 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003319 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3320 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3321 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003322 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003323 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003324}
3325
solenberg1ac56142015-10-13 03:58:19 -07003326TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003327 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003328 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003329 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3330 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3331 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003332 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003333 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003334 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3335 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003336 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003337 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003338 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003339 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003340}
3341
solenberg4bac9c52015-10-09 02:32:53 -07003342TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003343 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003344 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003345 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003346 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003347 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003348 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3349 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3350 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003351}
3352
solenberg2100c0b2017-03-01 11:29:29 -08003353TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003354 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003355
3356 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003357 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003358 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3359
3360 // Should remember the volume "2" which will be set on new unsignaled streams,
3361 // and also set the gain to 2 on existing unsignaled streams.
3362 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3363 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3364
3365 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3366 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3367 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3368 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3369 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3370 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3371
3372 // Setting gain with SSRC=0 should affect all unsignaled streams.
3373 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003374 if (kMaxUnsignaledRecvStreams > 1) {
3375 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3376 }
solenberg2100c0b2017-03-01 11:29:29 -08003377 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3378
3379 // Setting gain on an individual stream affects only that.
3380 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003381 if (kMaxUnsignaledRecvStreams > 1) {
3382 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3383 }
solenberg2100c0b2017-03-01 11:29:29 -08003384 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003385}
3386
pbos8fc7fa72015-07-15 08:02:58 -07003387TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003388 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003389 const std::string kSyncLabel = "AvSyncLabel";
3390
solenbergff976312016-03-30 23:28:51 -07003391 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003392 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3393 sp.sync_label = kSyncLabel;
3394 // Creating two channels to make sure that sync label is set properly for both
3395 // the default voice channel and following ones.
3396 EXPECT_TRUE(channel_->AddRecvStream(sp));
3397 sp.ssrcs[0] += 1;
3398 EXPECT_TRUE(channel_->AddRecvStream(sp));
3399
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003400 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003401 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003402 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003403 << "SyncGroup should be set based on sync_label";
3404 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003405 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003406 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003407}
3408
solenberg3a941542015-11-16 07:34:50 -08003409// TODO(solenberg): Remove, once recv streams are configured through Call.
3410// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003411TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003412 // Test that setting the header extensions results in the expected state
3413 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003414 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003415 ssrcs.push_back(223);
3416 ssrcs.push_back(224);
3417
solenbergff976312016-03-30 23:28:51 -07003418 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003419 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003420 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003421 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003422 cricket::StreamParams::CreateLegacy(ssrc)));
3423 }
3424
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003425 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003426 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003427 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003428 EXPECT_NE(nullptr, s);
3429 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3430 }
3431
3432 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003433 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003434 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003435 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003436 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003437 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003438 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003439 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003440 EXPECT_NE(nullptr, s);
3441 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003442 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3443 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003444 for (const auto& s_ext : s_exts) {
3445 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003446 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003447 }
3448 }
3449 }
3450 }
3451
3452 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003453 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003454 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003455 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003456 EXPECT_NE(nullptr, s);
3457 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3458 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003459}
3460
3461TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3462 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003463 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003464 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003465 static const unsigned char kRtcp[] = {
3466 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3467 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3470 };
jbaucheec21bd2016-03-20 06:15:43 -07003471 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003472
solenbergff976312016-03-30 23:28:51 -07003473 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003474 cricket::WebRtcVoiceMediaChannel* media_channel =
3475 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003476 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003477 EXPECT_TRUE(media_channel->AddRecvStream(
3478 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3479
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003480 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003481 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003482 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003483 EXPECT_EQ(0, s->received_packets());
3484 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3485 EXPECT_EQ(1, s->received_packets());
3486 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3487 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003488}
Minyue2013aec2015-05-13 14:14:42 +02003489
solenberg0a617e22015-10-20 15:49:38 -07003490// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003491// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003492TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003493 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003494 EXPECT_TRUE(AddRecvStream(kSsrcY));
3495 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003496 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003497 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3498 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3499 EXPECT_TRUE(AddRecvStream(kSsrcW));
3500 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003501}
3502
solenberg7602aab2016-11-14 11:30:07 -08003503TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3504 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003505 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003506 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003507 cricket::StreamParams::CreateLegacy(kSsrcY)));
3508 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3509 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3510 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003511 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003512 cricket::StreamParams::CreateLegacy(kSsrcW)));
3513 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3514 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003515}
stefan658910c2015-09-03 05:48:32 -07003516
deadbeef884f5852016-01-15 09:20:04 -08003517TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003518 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003519 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3520 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003521
3522 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003523 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3524 EXPECT_TRUE(AddRecvStream(kSsrcX));
3525 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003526
3527 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003528 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3529 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003530
3531 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003532 channel_->SetRawAudioSink(kSsrcX, nullptr);
3533 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003534}
3535
solenberg2100c0b2017-03-01 11:29:29 -08003536TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003537 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003538 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3539 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003540 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3541 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003542
3543 // Should be able to set a default sink even when no stream exists.
3544 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3545
solenberg2100c0b2017-03-01 11:29:29 -08003546 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3547 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003548 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003549 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003550
3551 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003552 channel_->SetRawAudioSink(kSsrc0, nullptr);
3553 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003554
3555 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003556 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3557 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003558
3559 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003560 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003561 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003562 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3563
3564 // Spawn another unsignaled stream - it should be assigned the default sink
3565 // and the previous unsignaled stream should lose it.
3566 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3567 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3568 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3569 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003570 if (kMaxUnsignaledRecvStreams > 1) {
3571 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3572 }
solenberg2100c0b2017-03-01 11:29:29 -08003573 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3574
3575 // Reset the default sink - the second unsignaled stream should lose it.
3576 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003577 if (kMaxUnsignaledRecvStreams > 1) {
3578 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3579 }
solenberg2100c0b2017-03-01 11:29:29 -08003580 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3581
3582 // Try setting the default sink while two streams exists.
3583 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003584 if (kMaxUnsignaledRecvStreams > 1) {
3585 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3586 }
solenberg2100c0b2017-03-01 11:29:29 -08003587 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3588
3589 // Try setting the sink for the first unsignaled stream using its known SSRC.
3590 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003591 if (kMaxUnsignaledRecvStreams > 1) {
3592 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3593 }
solenberg2100c0b2017-03-01 11:29:29 -08003594 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003595 if (kMaxUnsignaledRecvStreams > 1) {
3596 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3597 }
deadbeef884f5852016-01-15 09:20:04 -08003598}
3599
skvlad7a43d252016-03-22 15:32:27 -07003600// Test that, just like the video channel, the voice channel communicates the
3601// network state to the call.
3602TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003603 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003604
3605 EXPECT_EQ(webrtc::kNetworkUp,
3606 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3607 EXPECT_EQ(webrtc::kNetworkUp,
3608 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3609
3610 channel_->OnReadyToSend(false);
3611 EXPECT_EQ(webrtc::kNetworkDown,
3612 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3613 EXPECT_EQ(webrtc::kNetworkUp,
3614 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3615
3616 channel_->OnReadyToSend(true);
3617 EXPECT_EQ(webrtc::kNetworkUp,
3618 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3619 EXPECT_EQ(webrtc::kNetworkUp,
3620 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3621}
3622
aleloi18e0b672016-10-04 02:45:47 -07003623// Test that playout is still started after changing parameters
3624TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3625 SetupRecvStream();
3626 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003627 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003628
3629 // Changing RTP header extensions will recreate the AudioReceiveStream.
3630 cricket::AudioRecvParameters parameters;
3631 parameters.extensions.push_back(
3632 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3633 channel_->SetRecvParameters(parameters);
3634
solenberg2100c0b2017-03-01 11:29:29 -08003635 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003636}
3637
stefan658910c2015-09-03 05:48:32 -07003638// Tests that the library initializes and shuts down properly.
3639TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003640 // If the VoiceEngine wants to gather available codecs early, that's fine but
3641 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003642 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003643 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003644 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003645 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003646 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003647 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3648 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003649 EXPECT_TRUE(channel != nullptr);
3650 delete channel;
solenbergff976312016-03-30 23:28:51 -07003651}
stefan658910c2015-09-03 05:48:32 -07003652
solenbergff976312016-03-30 23:28:51 -07003653// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003654TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3655 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3656 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3657 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003658 // Return 100ms just in case this function gets called. If we don't,
3659 // we could enter a tight loop since the mock would return 0.
3660 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003661 {
ossuc54071d2016-08-17 02:45:41 -07003662 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003663 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003664 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003665 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003666 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003667 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3668 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3669 EXPECT_TRUE(channel != nullptr);
3670 delete channel;
3671 }
stefan658910c2015-09-03 05:48:32 -07003672}
3673
3674// Tests that the library is configured with the codecs we want.
3675TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003676 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3677 // module.
3678
stefan658910c2015-09-03 05:48:32 -07003679 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003680#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003681 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003682 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003683#endif
3684#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003685 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003686 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003687#endif
3688#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003689 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003690 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003691#endif
3692#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003693 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003694 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003695 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003696 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003697 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003698#endif
solenberg26c8c912015-11-27 04:00:25 -08003699 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003700 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003701 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003702 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003703 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003704 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003705 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3706 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3707 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3708 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3709 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3710 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003711 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003712 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003713 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003714 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003715 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003716 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003717 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003718 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003719 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003720 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003721 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003722 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003723 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003724 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003725 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003726 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003727 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003728 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003729 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003730 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003731 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003732 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003733 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003734
stefan658910c2015-09-03 05:48:32 -07003735 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003736 // TODO(ossu): Why are the payload types of codecs with non-static payload
3737 // type assignments checked here? It shouldn't really matter.
3738 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003739 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003740 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3741 if (codec.name == "CN" && codec.clockrate == 16000) {
3742 EXPECT_EQ(105, codec.id);
3743 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3744 EXPECT_EQ(106, codec.id);
3745 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3746 EXPECT_EQ(103, codec.id);
3747 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3748 EXPECT_EQ(104, codec.id);
3749 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3750 EXPECT_EQ(9, codec.id);
3751 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3752 EXPECT_EQ(126, codec.id);
3753 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3754 // Remove these checks once both send and receive side assigns payload types
3755 // dynamically.
3756 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3757 EXPECT_EQ(113, codec.id);
3758 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3759 EXPECT_EQ(112, codec.id);
3760 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3761 EXPECT_EQ(110, codec.id);
3762 } else if (codec.name == "opus") {
3763 EXPECT_EQ(111, codec.id);
3764 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3765 EXPECT_EQ("10", codec.params.find("minptime")->second);
3766 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3767 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003768 }
3769 }
stefan658910c2015-09-03 05:48:32 -07003770}
3771
3772// Tests that VoE supports at least 32 channels
3773TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003774 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003775 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003776 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003777 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003778 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003779
3780 cricket::VoiceMediaChannel* channels[32];
3781 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003782 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003783 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3784 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003785 if (!channel)
3786 break;
stefan658910c2015-09-03 05:48:32 -07003787 channels[num_channels++] = channel;
3788 }
3789
tfarina5237aaf2015-11-10 23:44:30 -08003790 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003791 EXPECT_EQ(expected, num_channels);
3792
3793 while (num_channels > 0) {
3794 delete channels[--num_channels];
3795 }
stefan658910c2015-09-03 05:48:32 -07003796}
3797
3798// Test that we set our preferred codecs properly.
3799TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003800 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3801 // - Check that our builtin codecs are usable by Channel.
3802 // - The codecs provided by the engine is usable by Channel.
3803 // It does not check that the codecs in the RecvParameters are actually
3804 // what we sent in - though it's probably reasonable to expect so, if
3805 // SetRecvParameters returns true.
3806 // I think it will become clear once audio decoder injection is completed.
3807 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003808 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003809 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003810 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003811 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003812 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3813 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003814 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003815 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003816 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003817}
ossu9def8002017-02-09 05:14:32 -08003818
3819TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3820 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003821 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3822 {48000, 2, 16000, 10000, 20000}};
3823 spec1.info.allow_comfort_noise = false;
3824 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003825 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003826 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3827 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003828 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003829 specs.push_back(webrtc::AudioCodecSpec{
3830 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3831 {16000, 1, 13300}});
3832 specs.push_back(
3833 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3834 specs.push_back(
3835 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003836
3837 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3838 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3839 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3840 .WillOnce(Return(specs));
3841
3842 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3843 auto codecs = engine.recv_codecs();
3844 EXPECT_EQ(11, codecs.size());
3845
3846 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3847 // check the actual values safely, to provide better test results.
3848 auto get_codec =
3849 [&codecs](size_t index) -> const cricket::AudioCodec& {
3850 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3851 if (codecs.size() > index)
3852 return codecs[index];
3853 return missing_codec;
3854 };
3855
3856 // Ensure the general codecs are generated first and in order.
3857 for (size_t i = 0; i != specs.size(); ++i) {
3858 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3859 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3860 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3861 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3862 }
3863
3864 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003865 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003866 auto find_codec =
3867 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3868 for (size_t i = 0; i != codecs.size(); ++i) {
3869 const cricket::AudioCodec& codec = codecs[i];
3870 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3871 codec.clockrate == format.clockrate_hz &&
3872 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003873 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003874 }
3875 }
3876 return -1;
3877 };
3878
3879 // Ensure all supplementary codecs are generated last. Their internal ordering
3880 // is not important.
3881 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3882 const int num_specs = static_cast<int>(specs.size());
3883 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3884 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3885 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3886 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3887 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3888 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3889 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3890}