blob: 735f36eaa70f52f2b826179ec5cdc8fb4712a7fe [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);
ossu20a4b3f2017-04-27 02:08:52 -070044const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070045const 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
ossu20a4b3f2017-04-27 02:08:52 -0700365 void CheckSendCodecBitrate(int32_t ssrc,
366 const char expected_name[],
367 int expected_bitrate) {
368 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
369 EXPECT_EQ(expected_name, spec->format.name);
370 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700371 }
372
ossu20a4b3f2017-04-27 02:08:52 -0700373 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
374 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700375 }
376
minyue6b825df2016-10-31 04:08:32 -0700377 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
378 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
379 }
380
skvlade0d46372016-04-07 22:59:22 -0700381 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
382 int global_max,
383 int stream_max,
384 bool expected_result,
385 int expected_codec_bitrate) {
386 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800387 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700388
389 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700390 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800391 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700392
393 // Verify that reading back the parameters gives results
394 // consistent with the Set() result.
395 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800396 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700397 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
398 EXPECT_EQ(expected_result ? stream_max : -1,
399 resulting_parameters.encodings[0].max_bitrate_bps);
400
401 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800402 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700403 }
404
stefan13f1a0a2016-11-30 07:22:58 -0800405 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
406 int expected_min_bitrate_bps,
407 const char* start_bitrate_kbps,
408 int expected_start_bitrate_bps,
409 const char* max_bitrate_kbps,
410 int expected_max_bitrate_bps) {
411 EXPECT_TRUE(SetupSendStream());
412 auto& codecs = send_parameters_.codecs;
413 codecs.clear();
414 codecs.push_back(kOpusCodec);
415 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
416 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
417 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
418 SetSendParameters(send_parameters_);
419
420 EXPECT_EQ(expected_min_bitrate_bps,
421 call_.GetConfig().bitrate_config.min_bitrate_bps);
422 EXPECT_EQ(expected_start_bitrate_bps,
423 call_.GetConfig().bitrate_config.start_bitrate_bps);
424 EXPECT_EQ(expected_max_bitrate_bps,
425 call_.GetConfig().bitrate_config.max_bitrate_bps);
426 }
427
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000428 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700429 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000430
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000431 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800432 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000433
434 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700435 send_parameters_.extensions.push_back(
436 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700437 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800438 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000439
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000440 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200441 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700442 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800443 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000444
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000445 // Ensure extension is set properly.
446 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700447 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700448 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800449 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
450 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
451 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000452
solenberg7add0582015-11-20 09:59:34 -0800453 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000454 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800455 cricket::StreamParams::CreateLegacy(kSsrcY)));
456 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
457 call_.GetAudioSendStream(kSsrcY));
458 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
459 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
460 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000461
462 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200463 send_parameters_.codecs.push_back(kPcmuCodec);
464 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700465 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800466 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
467 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000468 }
469
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000470 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700471 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000472
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000473 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800474 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000475
476 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700477 recv_parameters_.extensions.push_back(
478 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800479 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800480 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000481
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000482 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800483 recv_parameters_.extensions.clear();
484 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800485 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000486
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000487 // Ensure extension is set properly.
488 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700489 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800490 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800491 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
492 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
493 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000494
solenberg7add0582015-11-20 09:59:34 -0800495 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800496 EXPECT_TRUE(AddRecvStream(kSsrcY));
497 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
498 call_.GetAudioReceiveStream(kSsrcY));
499 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
500 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
501 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000502
503 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800504 recv_parameters_.extensions.clear();
505 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800506 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
507 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000508 }
509
solenberg85a04962015-10-27 03:35:21 -0700510 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
511 webrtc::AudioSendStream::Stats stats;
512 stats.local_ssrc = 12;
513 stats.bytes_sent = 345;
514 stats.packets_sent = 678;
515 stats.packets_lost = 9012;
516 stats.fraction_lost = 34.56f;
517 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800518 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700519 stats.ext_seqnum = 789;
520 stats.jitter_ms = 12;
521 stats.rtt_ms = 345;
522 stats.audio_level = 678;
523 stats.aec_quality_min = 9.01f;
524 stats.echo_delay_median_ms = 234;
525 stats.echo_delay_std_ms = 567;
526 stats.echo_return_loss = 890;
527 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700528 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800529 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700530 stats.typing_noise_detected = true;
531 return stats;
532 }
533 void SetAudioSendStreamStats() {
534 for (auto* s : call_.GetAudioSendStreams()) {
535 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200536 }
solenberg85a04962015-10-27 03:35:21 -0700537 }
solenberg566ef242015-11-06 15:34:49 -0800538 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
539 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700540 const auto stats = GetAudioSendStreamStats();
541 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
542 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
543 EXPECT_EQ(info.packets_sent, stats.packets_sent);
544 EXPECT_EQ(info.packets_lost, stats.packets_lost);
545 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
546 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800547 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700548 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
549 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
550 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
551 EXPECT_EQ(info.audio_level, stats.audio_level);
552 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
553 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
554 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
555 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
556 EXPECT_EQ(info.echo_return_loss_enhancement,
557 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700558 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800559 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
560 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800561 EXPECT_EQ(info.typing_noise_detected,
562 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700563 }
564
565 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
566 webrtc::AudioReceiveStream::Stats stats;
567 stats.remote_ssrc = 123;
568 stats.bytes_rcvd = 456;
569 stats.packets_rcvd = 768;
570 stats.packets_lost = 101;
571 stats.fraction_lost = 23.45f;
572 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800573 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700574 stats.ext_seqnum = 678;
575 stats.jitter_ms = 901;
576 stats.jitter_buffer_ms = 234;
577 stats.jitter_buffer_preferred_ms = 567;
578 stats.delay_estimate_ms = 890;
579 stats.audio_level = 1234;
580 stats.expand_rate = 5.67f;
581 stats.speech_expand_rate = 8.90f;
582 stats.secondary_decoded_rate = 1.23f;
583 stats.accelerate_rate = 4.56f;
584 stats.preemptive_expand_rate = 7.89f;
585 stats.decoding_calls_to_silence_generator = 12;
586 stats.decoding_calls_to_neteq = 345;
587 stats.decoding_normal = 67890;
588 stats.decoding_plc = 1234;
589 stats.decoding_cng = 5678;
590 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700591 stats.decoding_muted_output = 3456;
592 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200593 return stats;
594 }
595 void SetAudioReceiveStreamStats() {
596 for (auto* s : call_.GetAudioReceiveStreams()) {
597 s->SetStats(GetAudioReceiveStreamStats());
598 }
599 }
600 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700601 const auto stats = GetAudioReceiveStreamStats();
602 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
603 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
604 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
605 EXPECT_EQ(info.packets_lost, stats.packets_lost);
606 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
607 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800608 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700609 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
610 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
611 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200612 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700613 stats.jitter_buffer_preferred_ms);
614 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
615 EXPECT_EQ(info.audio_level, stats.audio_level);
616 EXPECT_EQ(info.expand_rate, stats.expand_rate);
617 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
618 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
619 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
620 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200621 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700622 stats.decoding_calls_to_silence_generator);
623 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
624 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
625 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
626 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
627 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700628 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700629 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200630 }
hbos1acfbd22016-11-17 23:43:29 -0800631 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
632 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
633 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
634 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
635 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
636 codec.ToCodecParameters());
637 }
638 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
639 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
640 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
641 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
642 codec.ToCodecParameters());
643 }
644 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200645
peah8271d042016-11-22 07:24:52 -0800646 bool IsHighPassFilterEnabled() {
647 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
648 }
649
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700651 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700652 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800653 webrtc::test::MockGainControl& apm_gc_;
654 webrtc::test::MockEchoCancellation& apm_ec_;
655 webrtc::test::MockNoiseSuppression& apm_ns_;
656 webrtc::test::MockVoiceDetection& apm_vd_;
657 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700658 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200659 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000660 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700661 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700662 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200663 cricket::AudioSendParameters send_parameters_;
664 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800665 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800666 private:
667 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668};
669
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670// Tests that we can create and destroy a channel.
671TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700672 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673}
674
solenberg31fec402016-05-06 02:13:12 -0700675// Test that we can add a send stream and that it has the correct defaults.
676TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
677 EXPECT_TRUE(SetupChannel());
678 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800679 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
680 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
681 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700682 EXPECT_EQ("", config.rtp.c_name);
683 EXPECT_EQ(0u, config.rtp.extensions.size());
684 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
685 config.send_transport);
686}
687
688// Test that we can add a receive stream and that it has the correct defaults.
689TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
690 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800691 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700692 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800693 GetRecvStreamConfig(kSsrcX);
694 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700695 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
696 EXPECT_FALSE(config.rtp.transport_cc);
697 EXPECT_EQ(0u, config.rtp.extensions.size());
698 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
699 config.rtcp_send_transport);
700 EXPECT_EQ("", config.sync_group);
701}
702
stefanba4c0e42016-02-04 04:12:24 -0800703TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700704 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800705 bool opus_found = false;
706 for (cricket::AudioCodec codec : codecs) {
707 if (codec.name == "opus") {
708 EXPECT_TRUE(HasTransportCc(codec));
709 opus_found = true;
710 }
711 }
712 EXPECT_TRUE(opus_found);
713}
714
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715// Test that we set our inbound codecs properly, including changing PT.
716TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700717 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200718 cricket::AudioRecvParameters parameters;
719 parameters.codecs.push_back(kIsacCodec);
720 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800721 parameters.codecs.push_back(kTelephoneEventCodec1);
722 parameters.codecs.push_back(kTelephoneEventCodec2);
723 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200724 parameters.codecs[2].id = 126;
725 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800726 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700727 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
728 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
729 {{0, {"PCMU", 8000, 1}},
730 {106, {"ISAC", 16000, 1}},
731 {126, {"telephone-event", 8000, 1}},
732 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733}
734
735// Test that we fail to set an unknown inbound codec.
736TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700737 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200738 cricket::AudioRecvParameters parameters;
739 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700740 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200741 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742}
743
744// Test that we fail if we have duplicate types in the inbound list.
745TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700746 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200747 cricket::AudioRecvParameters parameters;
748 parameters.codecs.push_back(kIsacCodec);
749 parameters.codecs.push_back(kCn16000Codec);
750 parameters.codecs[1].id = kIsacCodec.id;
751 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000752}
753
754// Test that we can decode OPUS without stereo parameters.
755TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700756 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200757 cricket::AudioRecvParameters parameters;
758 parameters.codecs.push_back(kIsacCodec);
759 parameters.codecs.push_back(kPcmuCodec);
760 parameters.codecs.push_back(kOpusCodec);
761 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800762 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700763 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
764 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
765 {{0, {"PCMU", 8000, 1}},
766 {103, {"ISAC", 16000, 1}},
767 {111, {"opus", 48000, 2}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768}
769
770// Test that we can decode OPUS with stereo = 0.
771TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700772 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200773 cricket::AudioRecvParameters parameters;
774 parameters.codecs.push_back(kIsacCodec);
775 parameters.codecs.push_back(kPcmuCodec);
776 parameters.codecs.push_back(kOpusCodec);
777 parameters.codecs[2].params["stereo"] = "0";
778 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800779 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700780 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
781 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
782 {{0, {"PCMU", 8000, 1}},
783 {103, {"ISAC", 16000, 1}},
784 {111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
787// Test that we can decode OPUS with stereo = 1.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700789 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200790 cricket::AudioRecvParameters parameters;
791 parameters.codecs.push_back(kIsacCodec);
792 parameters.codecs.push_back(kPcmuCodec);
793 parameters.codecs.push_back(kOpusCodec);
794 parameters.codecs[2].params["stereo"] = "1";
795 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800796 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700797 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
798 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
799 {{0, {"PCMU", 8000, 1}},
800 {103, {"ISAC", 16000, 1}},
801 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802}
803
804// Test that changes to recv codecs are applied to all streams.
805TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700806 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200807 cricket::AudioRecvParameters parameters;
808 parameters.codecs.push_back(kIsacCodec);
809 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800810 parameters.codecs.push_back(kTelephoneEventCodec1);
811 parameters.codecs.push_back(kTelephoneEventCodec2);
812 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200813 parameters.codecs[2].id = 126;
814 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700815 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
816 EXPECT_TRUE(AddRecvStream(ssrc));
817 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
818 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
819 {{0, {"PCMU", 8000, 1}},
820 {106, {"ISAC", 16000, 1}},
821 {126, {"telephone-event", 8000, 1}},
822 {107, {"telephone-event", 32000, 1}}})));
823 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700827 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200828 cricket::AudioRecvParameters parameters;
829 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800830 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
solenberg2100c0b2017-03-01 11:29:29 -0800833 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800834 ASSERT_EQ(1, dm.count(106));
835 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000836}
837
838// Test that we can apply the same set of codecs again while playing.
839TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700840 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 cricket::AudioRecvParameters parameters;
842 parameters.codecs.push_back(kIsacCodec);
843 parameters.codecs.push_back(kCn16000Codec);
844 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700845 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847
deadbeefcb383672017-04-26 16:28:42 -0700848 // Remapping a payload type to a different codec should fail.
849 parameters.codecs[0] = kOpusCodec;
850 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200851 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800852 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that we can add a codec while playing.
856TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kCn16000Codec);
861 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700862 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200864 parameters.codecs.push_back(kOpusCodec);
865 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800866 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867}
868
deadbeefcb383672017-04-26 16:28:42 -0700869// Test that we accept adding the same codec with a different payload type.
870// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
871TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
872 EXPECT_TRUE(SetupRecvStream());
873 cricket::AudioRecvParameters parameters;
874 parameters.codecs.push_back(kIsacCodec);
875 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
876
877 ++parameters.codecs[0].id;
878 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
879}
880
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700882 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000884 // Test that when autobw is enabled, bitrate is kept as the default
885 // value. autobw is enabled for the following tests because the target
886 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887
888 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700889 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890
891 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700892 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893
ossu20a4b3f2017-04-27 02:08:52 -0700894 // opus, default bitrate == 32000 in mono.
895 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896}
897
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000898TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700899 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700902 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
903 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700904 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700907 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
908 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
909 // Rates above the max (510000) should be capped.
910 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911}
912
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000913TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700914 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000915
916 // Test that we can only set a maximum bitrate for a fixed-rate codec
917 // if it's bigger than the fixed rate.
918
919 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700920 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
921 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
922 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
923 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
924 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
925 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
926 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000927}
928
929TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700930 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 const int kDesiredBitrate = 128000;
932 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700933 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200934 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700935 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000936
937 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800938 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000939
solenberg2100c0b2017-03-01 11:29:29 -0800940 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000941}
942
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943// Test that bitrate cannot be set for CBR codecs.
944// Bitrate is ignored if it is higher than the fixed bitrate.
945// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000946TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700947 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
949 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700950 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800951 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200952
953 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700954 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800955 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200956
957 send_parameters_.max_bandwidth_bps = 128;
958 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800959 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960}
961
skvlade0d46372016-04-07 22:59:22 -0700962// Test that the per-stream bitrate limit and the global
963// bitrate limit both apply.
964TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
965 EXPECT_TRUE(SetupSendStream());
966
ossu20a4b3f2017-04-27 02:08:52 -0700967 // opus, default bitrate == 32000.
968 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700969 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
970 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
971 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
972
973 // CBR codecs allow both maximums to exceed the bitrate.
974 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
975 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
976 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
977 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
978
979 // CBR codecs don't allow per stream maximums to be too low.
980 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
981 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
982}
983
984// Test that an attempt to set RtpParameters for a stream that does not exist
985// fails.
986TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
987 EXPECT_TRUE(SetupChannel());
988 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800989 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700990 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
991
992 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -0800993 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -0700994}
995
996TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700997 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -0700998 // This test verifies that setting RtpParameters succeeds only if
999 // the structure contains exactly one encoding.
1000 // TODO(skvlad): Update this test when we start supporting setting parameters
1001 // for each encoding individually.
1002
1003 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001004 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001005 // Two or more encodings should result in failure.
1006 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001007 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001008 // Zero encodings should also fail.
1009 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001010 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001011}
1012
1013// Changing the SSRC through RtpParameters is not allowed.
1014TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1015 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001016 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001017 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001018 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001019}
1020
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001021// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001022// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001023TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1024 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001025 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001026 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001027 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001028 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001029 ASSERT_EQ(1u, parameters.encodings.size());
1030 ASSERT_TRUE(parameters.encodings[0].active);
1031 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001032 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1033 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001034
1035 // Now change it back to active and verify we resume sending.
1036 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001037 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1038 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001039}
1040
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001041// Test that SetRtpSendParameters configures the correct encoding channel for
1042// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001043TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1044 SetupForMultiSendStream();
1045 // Create send streams.
1046 for (uint32_t ssrc : kSsrcs4) {
1047 EXPECT_TRUE(
1048 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1049 }
1050 // Configure one stream to be limited by the stream config, another to be
1051 // limited by the global max, and the third one with no per-stream limit
1052 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001053 SetGlobalMaxBitrate(kOpusCodec, 32000);
1054 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1055 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001056 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1057
ossu20a4b3f2017-04-27 02:08:52 -07001058 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1059 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1060 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001061
1062 // Remove the global cap; the streams should switch to their respective
1063 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001064 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001065 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1066 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1067 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001068}
1069
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001070// Test that GetRtpSendParameters returns the currently configured codecs.
1071TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001072 EXPECT_TRUE(SetupSendStream());
1073 cricket::AudioSendParameters parameters;
1074 parameters.codecs.push_back(kIsacCodec);
1075 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001076 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001077
solenberg2100c0b2017-03-01 11:29:29 -08001078 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001079 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001080 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1081 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001082}
1083
deadbeefcb443432016-12-12 11:12:36 -08001084// Test that GetRtpSendParameters returns an SSRC.
1085TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1086 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001087 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001088 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001089 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001090}
1091
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001092// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001093TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001094 EXPECT_TRUE(SetupSendStream());
1095 cricket::AudioSendParameters parameters;
1096 parameters.codecs.push_back(kIsacCodec);
1097 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001098 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001099
solenberg2100c0b2017-03-01 11:29:29 -08001100 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001101
1102 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001103 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001104
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001105 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001106 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1107 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001108}
1109
minyuececec102017-03-27 13:04:25 -07001110// Test that max_bitrate_bps in send stream config gets updated correctly when
1111// SetRtpSendParameters is called.
1112TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1113 webrtc::test::ScopedFieldTrials override_field_trials(
1114 "WebRTC-Audio-SendSideBwe/Enabled/");
1115 EXPECT_TRUE(SetupSendStream());
1116 cricket::AudioSendParameters send_parameters;
1117 send_parameters.codecs.push_back(kOpusCodec);
1118 SetSendParameters(send_parameters);
1119
1120 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1121 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1122 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1123
1124 constexpr int kMaxBitrateBps = 6000;
1125 rtp_parameters.encodings[0].max_bitrate_bps =
1126 rtc::Optional<int>(kMaxBitrateBps);
1127 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1128
1129 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1130 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1131}
1132
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133// Test that GetRtpReceiveParameters returns the currently configured codecs.
1134TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1135 EXPECT_TRUE(SetupRecvStream());
1136 cricket::AudioRecvParameters parameters;
1137 parameters.codecs.push_back(kIsacCodec);
1138 parameters.codecs.push_back(kPcmuCodec);
1139 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1140
1141 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001142 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001143 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1144 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1145 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1146}
1147
deadbeefcb443432016-12-12 11:12:36 -08001148// Test that GetRtpReceiveParameters returns an SSRC.
1149TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1150 EXPECT_TRUE(SetupRecvStream());
1151 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001152 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001153 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001154 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001155}
1156
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001157// Test that if we set/get parameters multiple times, we get the same results.
1158TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1159 EXPECT_TRUE(SetupRecvStream());
1160 cricket::AudioRecvParameters parameters;
1161 parameters.codecs.push_back(kIsacCodec);
1162 parameters.codecs.push_back(kPcmuCodec);
1163 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1164
1165 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001166 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001167
1168 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001169 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001170
1171 // ... And this shouldn't change the params returned by
1172 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001173 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1174 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001175}
1176
deadbeef3bc15102017-04-20 19:25:07 -07001177// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1178// aren't signaled. It should return an empty "RtpEncodingParameters" when
1179// configured to receive an unsignaled stream and no packets have been received
1180// yet, and start returning the SSRC once a packet has been received.
1181TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1182 ASSERT_TRUE(SetupChannel());
1183 // Call necessary methods to configure receiving a default stream as
1184 // soon as it arrives.
1185 cricket::AudioRecvParameters parameters;
1186 parameters.codecs.push_back(kIsacCodec);
1187 parameters.codecs.push_back(kPcmuCodec);
1188 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1189
1190 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1191 // stream. Should return nothing.
1192 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1193
1194 // Set a sink for an unsignaled stream.
1195 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1196 // Value of "0" means "unsignaled stream".
1197 channel_->SetRawAudioSink(0, std::move(fake_sink));
1198
1199 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1200 // in this method means "unsignaled stream".
1201 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1202 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1203 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1204
1205 // Receive PCMU packet (SSRC=1).
1206 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1207
1208 // The |ssrc| member should still be unset.
1209 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1210 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1211 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1212}
1213
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001214// Test that we apply codecs properly.
1215TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001216 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001217 cricket::AudioSendParameters parameters;
1218 parameters.codecs.push_back(kIsacCodec);
1219 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001220 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001221 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001222 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001223 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001224 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1225 EXPECT_EQ(96, send_codec_spec.payload_type);
1226 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1227 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1228 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1229 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001230 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001231}
1232
ossu20a4b3f2017-04-27 02:08:52 -07001233// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1234// AudioSendStream.
1235TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001236 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001237 cricket::AudioSendParameters parameters;
1238 parameters.codecs.push_back(kIsacCodec);
1239 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001240 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001241 parameters.codecs[0].id = 96;
1242 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001243 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001244 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001245 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001246 // Calling SetSendCodec again with same codec which is already set.
1247 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001248 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001249 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001250}
1251
ossu20a4b3f2017-04-27 02:08:52 -07001252// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1253// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001254
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001255// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001256TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001257 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001258 cricket::AudioSendParameters parameters;
1259 parameters.codecs.push_back(kOpusCodec);
1260 parameters.codecs[0].bitrate = 0;
1261 parameters.codecs[0].clockrate = 50000;
1262 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001263}
1264
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001265// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001267 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001268 cricket::AudioSendParameters parameters;
1269 parameters.codecs.push_back(kOpusCodec);
1270 parameters.codecs[0].bitrate = 0;
1271 parameters.codecs[0].channels = 0;
1272 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001273}
1274
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001275// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001276TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001277 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001278 cricket::AudioSendParameters parameters;
1279 parameters.codecs.push_back(kOpusCodec);
1280 parameters.codecs[0].bitrate = 0;
1281 parameters.codecs[0].channels = 0;
1282 parameters.codecs[0].params["stereo"] = "1";
1283 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
1286// Test that if channel is 1 for opus and there's no stereo, we fail.
1287TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001288 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 cricket::AudioSendParameters parameters;
1290 parameters.codecs.push_back(kOpusCodec);
1291 parameters.codecs[0].bitrate = 0;
1292 parameters.codecs[0].channels = 1;
1293 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001294}
1295
1296// Test that if channel is 1 for opus and stereo=0, we fail.
1297TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001298 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001299 cricket::AudioSendParameters parameters;
1300 parameters.codecs.push_back(kOpusCodec);
1301 parameters.codecs[0].bitrate = 0;
1302 parameters.codecs[0].channels = 1;
1303 parameters.codecs[0].params["stereo"] = "0";
1304 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305}
1306
1307// Test that if channel is 1 for opus and stereo=1, we fail.
1308TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001309 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001310 cricket::AudioSendParameters parameters;
1311 parameters.codecs.push_back(kOpusCodec);
1312 parameters.codecs[0].bitrate = 0;
1313 parameters.codecs[0].channels = 1;
1314 parameters.codecs[0].params["stereo"] = "1";
1315 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316}
1317
ossu20a4b3f2017-04-27 02:08:52 -07001318// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001319TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
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(kOpusCodec);
1323 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001324 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001325 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326}
1327
ossu20a4b3f2017-04-27 02:08:52 -07001328// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001330 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001331 cricket::AudioSendParameters parameters;
1332 parameters.codecs.push_back(kOpusCodec);
1333 parameters.codecs[0].bitrate = 0;
1334 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001335 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001336 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001337}
1338
ossu20a4b3f2017-04-27 02:08:52 -07001339// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001340TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001341 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 cricket::AudioSendParameters parameters;
1343 parameters.codecs.push_back(kOpusCodec);
1344 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001345 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001347 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001348 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001349
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001350 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001351 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001352 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001353}
1354
ossu20a4b3f2017-04-27 02:08:52 -07001355// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001357 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001358 cricket::AudioSendParameters parameters;
1359 parameters.codecs.push_back(kOpusCodec);
1360 parameters.codecs[0].bitrate = 0;
1361 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001362 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001363 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001364}
1365
ossu20a4b3f2017-04-27 02:08:52 -07001366// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001368 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001369 cricket::AudioSendParameters parameters;
1370 parameters.codecs.push_back(kOpusCodec);
1371 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001372 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001373 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001374 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001375 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001376
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001378 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001379 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001380}
1381
ossu20a4b3f2017-04-27 02:08:52 -07001382// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
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 = 96000;
solenberg059fb442016-10-26 05:12:24 -07001388 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001389 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1390 EXPECT_EQ(111, spec.payload_type);
1391 EXPECT_EQ(96000, spec.target_bitrate_bps);
1392 EXPECT_EQ("opus", spec.format.name);
1393 EXPECT_EQ(2, spec.format.num_channels);
1394 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395}
1396
ossu20a4b3f2017-04-27 02:08:52 -07001397// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001399 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001400 cricket::AudioSendParameters parameters;
1401 parameters.codecs.push_back(kOpusCodec);
1402 parameters.codecs[0].bitrate = 30000;
1403 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001404 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001405 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406}
1407
ossu20a4b3f2017-04-27 02:08:52 -07001408// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001410 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 cricket::AudioSendParameters parameters;
1412 parameters.codecs.push_back(kOpusCodec);
1413 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001414 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001415 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416}
1417
ossu20a4b3f2017-04-27 02:08:52 -07001418// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001419TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001420 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 cricket::AudioSendParameters parameters;
1422 parameters.codecs.push_back(kOpusCodec);
1423 parameters.codecs[0].bitrate = 30000;
1424 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001425 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001426 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001427}
1428
stefan13f1a0a2016-11-30 07:22:58 -08001429TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1430 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1431 200000);
1432}
1433
1434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1435 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1436}
1437
1438TEST_F(WebRtcVoiceEngineTestFake,
1439 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1440 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1441}
1442
1443TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1444 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1445}
1446
1447TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001448 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001449 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1450 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001451 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001452 SetSendParameters(send_parameters_);
1453 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1454 << "Setting max bitrate should keep previous min bitrate.";
1455 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1456 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001457 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001458}
1459
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001460// Test that we can enable NACK with opus as caller.
1461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001462 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 cricket::AudioSendParameters parameters;
1464 parameters.codecs.push_back(kOpusCodec);
1465 parameters.codecs[0].AddFeedbackParam(
1466 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1467 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001468 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001469 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001470 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471}
1472
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001473// Test that we can enable NACK with opus as callee.
1474TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001475 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 cricket::AudioSendParameters parameters;
1477 parameters.codecs.push_back(kOpusCodec);
1478 parameters.codecs[0].AddFeedbackParam(
1479 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1480 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001481 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001483 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001484 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001485
1486 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001487 cricket::StreamParams::CreateLegacy(kSsrcX)));
1488 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001489}
1490
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491// Test that we can enable NACK on receive streams.
1492TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001493 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001494 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001495 cricket::AudioSendParameters parameters;
1496 parameters.codecs.push_back(kOpusCodec);
1497 parameters.codecs[0].AddFeedbackParam(
1498 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1499 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001500 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1501 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001502 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001503 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1504 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505}
1506
1507// Test that we can disable NACK.
1508TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001509 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001510 cricket::AudioSendParameters parameters;
1511 parameters.codecs.push_back(kOpusCodec);
1512 parameters.codecs[0].AddFeedbackParam(
1513 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1514 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001515 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001516 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001518 parameters.codecs.clear();
1519 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001520 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001521 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522}
1523
1524// Test that we can disable NACK on receive streams.
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001526 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001527 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001528 cricket::AudioSendParameters parameters;
1529 parameters.codecs.push_back(kOpusCodec);
1530 parameters.codecs[0].AddFeedbackParam(
1531 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1532 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001533 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001534 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1535 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001536
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 parameters.codecs.clear();
1538 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001539 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001540 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1541 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001542}
1543
1544// Test that NACK is enabled on a new receive stream.
1545TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001546 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001547 cricket::AudioSendParameters parameters;
1548 parameters.codecs.push_back(kIsacCodec);
1549 parameters.codecs.push_back(kCn16000Codec);
1550 parameters.codecs[0].AddFeedbackParam(
1551 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1552 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001553 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001554 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001555
solenberg2100c0b2017-03-01 11:29:29 -08001556 EXPECT_TRUE(AddRecvStream(kSsrcY));
1557 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1558 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1559 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560}
1561
stefanba4c0e42016-02-04 04:12:24 -08001562TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001564 cricket::AudioSendParameters send_parameters;
1565 send_parameters.codecs.push_back(kOpusCodec);
1566 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001567 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001568
1569 cricket::AudioRecvParameters recv_parameters;
1570 recv_parameters.codecs.push_back(kIsacCodec);
1571 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001572 EXPECT_TRUE(AddRecvStream(kSsrcX));
1573 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001574 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001575 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001576
ossudedfd282016-06-14 07:12:39 -07001577 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001578 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001579 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001580 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001581 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001582}
1583
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001584// Test that we can switch back and forth between Opus and ISAC with CN.
1585TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001586 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001588 cricket::AudioSendParameters opus_parameters;
1589 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001590 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001591 {
ossu20a4b3f2017-04-27 02:08:52 -07001592 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1593 EXPECT_EQ(111, spec.payload_type);
1594 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001595 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001597 cricket::AudioSendParameters isac_parameters;
1598 isac_parameters.codecs.push_back(kIsacCodec);
1599 isac_parameters.codecs.push_back(kCn16000Codec);
1600 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001601 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001602 {
ossu20a4b3f2017-04-27 02:08:52 -07001603 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1604 EXPECT_EQ(103, spec.payload_type);
1605 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001606 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607
solenberg059fb442016-10-26 05:12:24 -07001608 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001609 {
ossu20a4b3f2017-04-27 02:08:52 -07001610 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1611 EXPECT_EQ(111, spec.payload_type);
1612 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001613 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
1616// Test that we handle various ways of specifying bitrate.
1617TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001618 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001619 cricket::AudioSendParameters parameters;
1620 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001621 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001622 {
ossu20a4b3f2017-04-27 02:08:52 -07001623 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1624 EXPECT_EQ(103, spec.payload_type);
1625 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1626 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001627 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001628
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001629 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001630 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001631 {
ossu20a4b3f2017-04-27 02:08:52 -07001632 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1633 EXPECT_EQ(103, spec.payload_type);
1634 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1635 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001636 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001637 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001638 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001639 {
ossu20a4b3f2017-04-27 02:08:52 -07001640 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1641 EXPECT_EQ(103, spec.payload_type);
1642 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1643 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001644 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001645
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001647 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001648 {
ossu20a4b3f2017-04-27 02:08:52 -07001649 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1650 EXPECT_EQ(0, spec.payload_type);
1651 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1652 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001653 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001654
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001655 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001656 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001657 {
ossu20a4b3f2017-04-27 02:08:52 -07001658 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1659 EXPECT_EQ(0, spec.payload_type);
1660 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1661 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001662 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001663
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001664 parameters.codecs[0] = kOpusCodec;
1665 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001666 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001667 {
ossu20a4b3f2017-04-27 02:08:52 -07001668 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1669 EXPECT_EQ(111, spec.payload_type);
1670 EXPECT_STREQ("opus", spec.format.name.c_str());
1671 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001672 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001673}
1674
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001675// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001676TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001677 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001678 cricket::AudioSendParameters parameters;
1679 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001680}
1681
1682// Test that we can set send codecs even with telephone-event codec as the first
1683// one on the list.
1684TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001685 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001686 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001687 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 parameters.codecs.push_back(kIsacCodec);
1689 parameters.codecs.push_back(kPcmuCodec);
1690 parameters.codecs[0].id = 98; // DTMF
1691 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001693 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1694 EXPECT_EQ(96, spec.payload_type);
1695 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001696 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001697}
1698
solenberg31642aa2016-03-14 08:00:37 -07001699// Test that payload type range is limited for telephone-event codec.
1700TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001701 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001702 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001703 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001704 parameters.codecs.push_back(kIsacCodec);
1705 parameters.codecs[0].id = 0; // DTMF
1706 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001707 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001708 EXPECT_TRUE(channel_->CanInsertDtmf());
1709 parameters.codecs[0].id = 128; // DTMF
1710 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1711 EXPECT_FALSE(channel_->CanInsertDtmf());
1712 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001713 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001714 EXPECT_TRUE(channel_->CanInsertDtmf());
1715 parameters.codecs[0].id = -1; // DTMF
1716 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1717 EXPECT_FALSE(channel_->CanInsertDtmf());
1718}
1719
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001720// Test that we can set send codecs even with CN codec as the first
1721// one on the list.
1722TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001723 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001724 cricket::AudioSendParameters parameters;
1725 parameters.codecs.push_back(kCn16000Codec);
1726 parameters.codecs.push_back(kIsacCodec);
1727 parameters.codecs.push_back(kPcmuCodec);
1728 parameters.codecs[0].id = 98; // wideband CN
1729 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001730 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001731 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1732 EXPECT_EQ(96, send_codec_spec.payload_type);
1733 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001734 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735}
1736
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001737// Test that we set VAD and DTMF types correctly as caller.
1738TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001739 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 cricket::AudioSendParameters parameters;
1741 parameters.codecs.push_back(kIsacCodec);
1742 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 parameters.codecs.push_back(kCn16000Codec);
1745 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001746 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001747 parameters.codecs[0].id = 96;
1748 parameters.codecs[2].id = 97; // wideband CN
1749 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001751 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1752 EXPECT_EQ(96, send_codec_spec.payload_type);
1753 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1754 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001755 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001756 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757}
1758
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001759// Test that we set VAD and DTMF types correctly as callee.
1760TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001761 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001762 cricket::AudioSendParameters parameters;
1763 parameters.codecs.push_back(kIsacCodec);
1764 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001765 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001766 parameters.codecs.push_back(kCn16000Codec);
1767 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001768 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001769 parameters.codecs[0].id = 96;
1770 parameters.codecs[2].id = 97; // wideband CN
1771 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001772 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001773 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001774 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001775
ossu20a4b3f2017-04-27 02:08:52 -07001776 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1777 EXPECT_EQ(96, send_codec_spec.payload_type);
1778 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1779 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001780 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001781 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001782}
1783
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784// Test that we only apply VAD if we have a CN codec that matches the
1785// send codec clockrate.
1786TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001787 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001788 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001790 parameters.codecs.push_back(kIsacCodec);
1791 parameters.codecs.push_back(kCn16000Codec);
1792 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001794 {
ossu20a4b3f2017-04-27 02:08:52 -07001795 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1796 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1797 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001798 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001799 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001801 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07001802 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001803 {
ossu20a4b3f2017-04-27 02:08:52 -07001804 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1805 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1806 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001807 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001809 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001810 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001811 {
ossu20a4b3f2017-04-27 02:08:52 -07001812 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1813 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1814 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001815 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001816 }
Brave Yao5225dd82015-03-26 07:39:19 +08001817 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001819 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001820 {
ossu20a4b3f2017-04-27 02:08:52 -07001821 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1822 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1823 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001824 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825}
1826
1827// Test that we perform case-insensitive matching of codec names.
1828TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001829 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001830 cricket::AudioSendParameters parameters;
1831 parameters.codecs.push_back(kIsacCodec);
1832 parameters.codecs.push_back(kPcmuCodec);
1833 parameters.codecs.push_back(kCn16000Codec);
1834 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001835 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001836 parameters.codecs[0].name = "iSaC";
1837 parameters.codecs[0].id = 96;
1838 parameters.codecs[2].id = 97; // wideband CN
1839 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001840 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001841 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1842 EXPECT_EQ(96, send_codec_spec.payload_type);
1843 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1844 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001845 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001846 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001847}
1848
stefanba4c0e42016-02-04 04:12:24 -08001849class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1850 public:
1851 WebRtcVoiceEngineWithSendSideBweTest()
1852 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1853};
1854
1855TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1856 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001857 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001858 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001859 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1860 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1861 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001862 extension.id);
1863 return;
1864 }
1865 }
1866 FAIL() << "Transport sequence number extension not in header-extension list.";
1867}
1868
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001869// Test support for audio level header extension.
1870TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001871 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001872}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001873TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001874 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001875}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001876
solenbergd4adce42016-11-17 06:26:52 -08001877// Test support for transport sequence number header extension.
1878TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1879 TestSetSendRtpHeaderExtensions(
1880 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001881}
solenbergd4adce42016-11-17 06:26:52 -08001882TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1883 TestSetRecvRtpHeaderExtensions(
1884 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001885}
1886
solenberg1ac56142015-10-13 03:58:19 -07001887// Test that we can create a channel and start sending on it.
1888TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001889 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001890 SetSendParameters(send_parameters_);
1891 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001892 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001893 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001894 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001895}
1896
1897// Test that a channel will send if and only if it has a source and is enabled
1898// for sending.
1899TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001900 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001901 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001902 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001903 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001904 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1905 SetAudioSend(kSsrcX, true, &fake_source_);
1906 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1907 SetAudioSend(kSsrcX, true, nullptr);
1908 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001909}
1910
solenberg94218532016-06-16 10:53:22 -07001911// Test that a channel is muted/unmuted.
1912TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1913 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001914 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001915 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1916 SetAudioSend(kSsrcX, true, nullptr);
1917 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1918 SetAudioSend(kSsrcX, false, nullptr);
1919 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001920}
1921
solenberg6d6e7c52016-04-13 09:07:30 -07001922// Test that SetSendParameters() does not alter a stream's send state.
1923TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1924 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001925 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001926
1927 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001928 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001929 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001930
1931 // Changing RTP header extensions will recreate the AudioSendStream.
1932 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001933 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001934 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001935 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001936
1937 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001938 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001939 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001940
1941 // Changing RTP header extensions will recreate the AudioSendStream.
1942 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001943 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001944 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001945}
1946
solenberg1ac56142015-10-13 03:58:19 -07001947// Test that we can create a channel and start playing out on it.
1948TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001949 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001950 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001951 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001952 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001953 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001954 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955}
1956
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001957// Test that we can add and remove send streams.
1958TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1959 SetupForMultiSendStream();
1960
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001961 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001962 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001963
solenbergc96df772015-10-21 13:01:53 -07001964 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001965 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001966 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001967 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001968 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001969 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001970 }
tfarina5237aaf2015-11-10 23:44:30 -08001971 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001972
solenbergc96df772015-10-21 13:01:53 -07001973 // Delete the send streams.
1974 for (uint32_t ssrc : kSsrcs4) {
1975 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001976 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001977 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001978 }
solenbergc96df772015-10-21 13:01:53 -07001979 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001980}
1981
1982// Test SetSendCodecs correctly configure the codecs in all send streams.
1983TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1984 SetupForMultiSendStream();
1985
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001986 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07001987 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001988 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001989 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001990 }
1991
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001992 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001993 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001994 parameters.codecs.push_back(kIsacCodec);
1995 parameters.codecs.push_back(kCn16000Codec);
1996 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07001997 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001998
1999 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002000 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002001 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2002 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002003 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2004 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2005 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002006 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002007 }
2008
minyue7a973442016-10-20 03:27:12 -07002009 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002011 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002012 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002013 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2014 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002015 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2016 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2017 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002018 }
2019}
2020
2021// Test we can SetSend on all send streams correctly.
2022TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2023 SetupForMultiSendStream();
2024
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002025 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002026 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002028 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002029 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002030 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002031 }
2032
2033 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002034 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002035 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002036 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002037 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002038 }
2039
2040 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002041 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002042 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002043 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002044 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045 }
2046}
2047
2048// Test we can set the correct statistics on all send streams.
2049TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2050 SetupForMultiSendStream();
2051
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002053 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002054 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002055 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002056 }
solenberg85a04962015-10-27 03:35:21 -07002057
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002058 // Create a receive stream to check that none of the send streams end up in
2059 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002060 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002061
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002063 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002064 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002065 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002066
solenberg85a04962015-10-27 03:35:21 -07002067 // Check stats for the added streams.
2068 {
2069 cricket::VoiceMediaInfo info;
2070 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071
solenberg85a04962015-10-27 03:35:21 -07002072 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002073 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002074 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002075 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002076 }
hbos1acfbd22016-11-17 23:43:29 -08002077 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002078
2079 // We have added one receive stream. We should see empty stats.
2080 EXPECT_EQ(info.receivers.size(), 1u);
2081 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002082 }
solenberg1ac56142015-10-13 03:58:19 -07002083
solenberg2100c0b2017-03-01 11:29:29 -08002084 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002085 {
2086 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002087 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002088 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002089 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002090 EXPECT_EQ(0u, info.receivers.size());
2091 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002092
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002093 // Deliver a new packet - a default receive stream should be created and we
2094 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002095 {
2096 cricket::VoiceMediaInfo info;
2097 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2098 SetAudioReceiveStreamStats();
2099 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002100 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002101 EXPECT_EQ(1u, info.receivers.size());
2102 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002103 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002104 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002105}
2106
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002107// Test that we can add and remove receive streams, and do proper send/playout.
2108// We can receive on multiple streams while sending one stream.
2109TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002110 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111
solenberg1ac56142015-10-13 03:58:19 -07002112 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002113 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002114 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002115
solenberg1ac56142015-10-13 03:58:19 -07002116 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002117 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002118 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002119 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120
solenberg1ac56142015-10-13 03:58:19 -07002121 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002122 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002123
2124 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002125 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2126 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2127 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002128
2129 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002130 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002131 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132
2133 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002134 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002135 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2136 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137
aleloi84ef6152016-08-04 05:28:21 -07002138 // Restart playout and make sure recv streams are played out.
2139 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002140 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2141 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002142
aleloi84ef6152016-08-04 05:28:21 -07002143 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002144 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2145 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002146}
2147
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002149// and start sending on it.
2150TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002151 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002152 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2153 EXPECT_CALL(apm_gc_,
2154 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002155 SetSendParameters(send_parameters_);
2156 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002157 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002158 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002159 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002160}
2161
wu@webrtc.org97077a32013-10-25 21:18:33 +00002162TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002163 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002164 EXPECT_CALL(adm_,
2165 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002166 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2167 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002168 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2169 send_parameters_.options.tx_agc_digital_compression_gain =
2170 rtc::Optional<uint16_t>(9);
2171 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2172 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002173 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2174 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2175 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002176 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002177
2178 // Check interaction with adjust_agc_delta. Both should be respected, for
2179 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002180 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002181 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002182 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002183}
2184
wu@webrtc.org97077a32013-10-25 21:18:33 +00002185TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002186 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002187 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2188 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002189 send_parameters_.options.recording_sample_rate =
2190 rtc::Optional<uint32_t>(48000);
2191 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002192 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002193}
2194
minyue6b825df2016-10-31 04:08:32 -07002195TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2196 EXPECT_TRUE(SetupSendStream());
2197 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2198 send_parameters_.options.audio_network_adaptor_config =
2199 rtc::Optional<std::string>("1234");
2200 SetSendParameters(send_parameters_);
2201 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002202 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002203}
2204
2205TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2206 EXPECT_TRUE(SetupSendStream());
2207 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2208 send_parameters_.options.audio_network_adaptor_config =
2209 rtc::Optional<std::string>("1234");
2210 SetSendParameters(send_parameters_);
2211 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002212 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002213 cricket::AudioOptions options;
2214 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002215 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002216 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002217}
2218
2219TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2220 EXPECT_TRUE(SetupSendStream());
2221 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2222 send_parameters_.options.audio_network_adaptor_config =
2223 rtc::Optional<std::string>("1234");
2224 SetSendParameters(send_parameters_);
2225 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002226 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002227 const int initial_num = call_.GetNumCreatedSendStreams();
2228 cricket::AudioOptions options;
2229 options.audio_network_adaptor = rtc::Optional<bool>();
2230 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2231 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002232 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002233 // AudioSendStream not expected to be recreated.
2234 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2235 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002236 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002237}
2238
michaelt6672b262017-01-11 10:17:59 -08002239class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2240 : public WebRtcVoiceEngineTestFake {
2241 public:
2242 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2243 : WebRtcVoiceEngineTestFake(
2244 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2245 "Enabled/") {}
2246};
2247
2248TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2249 EXPECT_TRUE(SetupSendStream());
2250 cricket::AudioSendParameters parameters;
2251 parameters.codecs.push_back(kOpusCodec);
2252 SetSendParameters(parameters);
2253 const int initial_num = call_.GetNumCreatedSendStreams();
2254 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2255
2256 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2257 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002258 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2259 constexpr int kMinOverheadBps =
2260 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002261
2262 constexpr int kOpusMinBitrateBps = 6000;
2263 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002264 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002265 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002266 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002267 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002268
2269 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2270 parameters.options.audio_network_adaptor_config =
2271 rtc::Optional<std::string>("1234");
2272 SetSendParameters(parameters);
2273
ossu11bfc532017-02-16 05:37:06 -08002274 constexpr int kMinOverheadWithAnaBps =
2275 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002276
2277 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002278 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002279
minyuececec102017-03-27 13:04:25 -07002280 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002281 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002282}
2283
minyuececec102017-03-27 13:04:25 -07002284// This test is similar to
2285// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2286// additional field trial.
2287TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2288 SetRtpSendParameterUpdatesMaxBitrate) {
2289 EXPECT_TRUE(SetupSendStream());
2290 cricket::AudioSendParameters send_parameters;
2291 send_parameters.codecs.push_back(kOpusCodec);
2292 SetSendParameters(send_parameters);
2293
2294 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2295 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2296 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2297
2298 constexpr int kMaxBitrateBps = 6000;
2299 rtp_parameters.encodings[0].max_bitrate_bps =
2300 rtc::Optional<int>(kMaxBitrateBps);
2301 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2302
2303 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2304#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2305 constexpr int kMinOverhead = 3333;
2306#else
2307 constexpr int kMinOverhead = 6666;
2308#endif
2309 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2310}
2311
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002312// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002313// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002314TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002315 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002316 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317}
2318
2319TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2320 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002321 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002322 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002323 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002324 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002325 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002326 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002327 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002328
solenberg85a04962015-10-27 03:35:21 -07002329 // Check stats for the added streams.
2330 {
2331 cricket::VoiceMediaInfo info;
2332 EXPECT_EQ(true, channel_->GetStats(&info));
2333
2334 // We have added one send stream. We should see the stats we've set.
2335 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002336 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002337 // We have added one receive stream. We should see empty stats.
2338 EXPECT_EQ(info.receivers.size(), 1u);
2339 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2340 }
solenberg1ac56142015-10-13 03:58:19 -07002341
solenberg566ef242015-11-06 15:34:49 -08002342 // Start sending - this affects some reported stats.
2343 {
2344 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002345 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002346 EXPECT_EQ(true, channel_->GetStats(&info));
2347 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002348 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002349 }
2350
solenberg2100c0b2017-03-01 11:29:29 -08002351 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002352 {
2353 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002354 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002355 EXPECT_EQ(true, channel_->GetStats(&info));
2356 EXPECT_EQ(1u, info.senders.size());
2357 EXPECT_EQ(0u, info.receivers.size());
2358 }
solenberg1ac56142015-10-13 03:58:19 -07002359
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002360 // Deliver a new packet - a default receive stream should be created and we
2361 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002362 {
2363 cricket::VoiceMediaInfo info;
2364 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2365 SetAudioReceiveStreamStats();
2366 EXPECT_EQ(true, channel_->GetStats(&info));
2367 EXPECT_EQ(1u, info.senders.size());
2368 EXPECT_EQ(1u, info.receivers.size());
2369 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002370 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002371 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002372}
2373
2374// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002375// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002376TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002377 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002378 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2379 EXPECT_TRUE(AddRecvStream(kSsrcY));
2380 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381}
2382
2383// Test that the local SSRC is the same on sending and receiving channels if the
2384// receive channel is created before the send channel.
2385TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002386 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002387 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002389 cricket::StreamParams::CreateLegacy(kSsrcX)));
2390 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2391 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002392}
2393
2394// Test that we can properly receive packets.
2395TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002396 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002397 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002398 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002399
2400 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2401 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002402}
2403
2404// Test that we can properly receive packets on multiple streams.
2405TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002406 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002407 const uint32_t ssrc1 = 1;
2408 const uint32_t ssrc2 = 2;
2409 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002410 EXPECT_TRUE(AddRecvStream(ssrc1));
2411 EXPECT_TRUE(AddRecvStream(ssrc2));
2412 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002414 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002415 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002416 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002417 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418 }
mflodman3d7db262016-04-29 00:57:13 -07002419
2420 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2421 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2422 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2423
2424 EXPECT_EQ(s1.received_packets(), 0);
2425 EXPECT_EQ(s2.received_packets(), 0);
2426 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002427
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002429 EXPECT_EQ(s1.received_packets(), 0);
2430 EXPECT_EQ(s2.received_packets(), 0);
2431 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002432
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002434 EXPECT_EQ(s1.received_packets(), 1);
2435 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2436 EXPECT_EQ(s2.received_packets(), 0);
2437 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002438
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002439 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002440 EXPECT_EQ(s1.received_packets(), 1);
2441 EXPECT_EQ(s2.received_packets(), 1);
2442 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2443 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002444
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002445 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002446 EXPECT_EQ(s1.received_packets(), 1);
2447 EXPECT_EQ(s2.received_packets(), 1);
2448 EXPECT_EQ(s3.received_packets(), 1);
2449 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002450
mflodman3d7db262016-04-29 00:57:13 -07002451 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2452 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2453 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002454}
2455
solenberg2100c0b2017-03-01 11:29:29 -08002456// Test that receiving on an unsignaled stream works (a stream is created).
2457TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002458 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002459 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2460
solenberg7e63ef02015-11-20 00:19:43 -08002461 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002462
2463 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002464 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2465 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002466}
2467
solenberg2100c0b2017-03-01 11:29:29 -08002468// Test that receiving N unsignaled stream works (streams will be created), and
2469// that packets are forwarded to them all.
2470TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002471 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002472 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002473 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2474
solenberg2100c0b2017-03-01 11:29:29 -08002475 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002476 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002477 rtc::SetBE32(&packet[8], ssrc);
2478 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002479
solenberg2100c0b2017-03-01 11:29:29 -08002480 // Verify we have one new stream for each loop iteration.
2481 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002482 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2483 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002484 }
mflodman3d7db262016-04-29 00:57:13 -07002485
solenberg2100c0b2017-03-01 11:29:29 -08002486 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002487 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002488 rtc::SetBE32(&packet[8], ssrc);
2489 DeliverPacket(packet, sizeof(packet));
2490
solenbergebb349d2017-03-13 05:46:15 -07002491 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002492 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2493 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2494 }
2495
2496 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2497 constexpr uint32_t kAnotherSsrc = 667;
2498 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002499 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002500
2501 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002502 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002503 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002504 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002505 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2506 EXPECT_EQ(2, streams[i]->received_packets());
2507 }
2508 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2509 EXPECT_EQ(1, streams[i]->received_packets());
2510 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002511 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002512}
2513
solenberg2100c0b2017-03-01 11:29:29 -08002514// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002515// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002516TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002517 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002518 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002519 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2520
2521 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002522 const uint32_t signaled_ssrc = 1;
2523 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002524 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002525 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002526 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2527 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002528 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002529
2530 // Note that the first unknown SSRC cannot be 0, because we only support
2531 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002532 const uint32_t unsignaled_ssrc = 7011;
2533 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002534 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002535 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2536 packet, sizeof(packet)));
2537 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2538
2539 DeliverPacket(packet, sizeof(packet));
2540 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2541
2542 rtc::SetBE32(&packet[8], signaled_ssrc);
2543 DeliverPacket(packet, sizeof(packet));
2544 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2545 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002546}
2547
solenberg4904fb62017-02-17 12:01:14 -08002548// Two tests to verify that adding a receive stream with the same SSRC as a
2549// previously added unsignaled stream will only recreate underlying stream
2550// objects if the stream parameters have changed.
2551TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2552 EXPECT_TRUE(SetupChannel());
2553
2554 // Spawn unsignaled stream with SSRC=1.
2555 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2556 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2557 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2558 sizeof(kPcmuFrame)));
2559
2560 // Verify that the underlying stream object in Call is not recreated when a
2561 // stream with SSRC=1 is added.
2562 const auto& streams = call_.GetAudioReceiveStreams();
2563 EXPECT_EQ(1, streams.size());
2564 int audio_receive_stream_id = streams.front()->id();
2565 EXPECT_TRUE(AddRecvStream(1));
2566 EXPECT_EQ(1, streams.size());
2567 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2568}
2569
2570TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2571 EXPECT_TRUE(SetupChannel());
2572
2573 // Spawn unsignaled stream with SSRC=1.
2574 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2575 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2576 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2577 sizeof(kPcmuFrame)));
2578
2579 // Verify that the underlying stream object in Call *is* recreated when a
2580 // stream with SSRC=1 is added, and which has changed stream parameters.
2581 const auto& streams = call_.GetAudioReceiveStreams();
2582 EXPECT_EQ(1, streams.size());
2583 int audio_receive_stream_id = streams.front()->id();
2584 cricket::StreamParams stream_params;
2585 stream_params.ssrcs.push_back(1);
2586 stream_params.sync_label = "sync_label";
2587 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2588 EXPECT_EQ(1, streams.size());
2589 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2590}
2591
solenberg0a617e22015-10-20 15:49:38 -07002592// Test that we properly handle failures to add a receive stream.
2593TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002594 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002595 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002596 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002597}
2598
solenberg0a617e22015-10-20 15:49:38 -07002599// Test that we properly handle failures to add a send stream.
2600TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002601 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002602 voe_.set_fail_create_channel(true);
2603 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2604}
2605
solenberg1ac56142015-10-13 03:58:19 -07002606// Test that AddRecvStream creates new stream.
2607TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002608 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002609 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002610 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002611 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002612}
2613
2614// Test that after adding a recv stream, we do not decode more codecs than
2615// those previously passed into SetRecvCodecs.
2616TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002617 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002618 cricket::AudioRecvParameters parameters;
2619 parameters.codecs.push_back(kIsacCodec);
2620 parameters.codecs.push_back(kPcmuCodec);
2621 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002622 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002623 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2624 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2625 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626}
2627
2628// Test that we properly clean up any streams that were added, even if
2629// not explicitly removed.
2630TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002631 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002632 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002633 EXPECT_TRUE(AddRecvStream(1));
2634 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002635 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2636 delete channel_;
2637 channel_ = NULL;
2638 EXPECT_EQ(0, voe_.GetNumChannels());
2639}
2640
wu@webrtc.org78187522013-10-07 23:32:02 +00002641TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002642 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002643 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002644}
2645
2646TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002647 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002648 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002649 // Manually delete channel to simulate a failure.
2650 int channel = voe_.GetLastChannel();
2651 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2652 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002653 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002654 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002655 EXPECT_NE(channel, new_channel);
2656 // The last created channel is deleted too.
2657 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002658}
2659
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002660// Test the InsertDtmf on default send stream as caller.
2661TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002662 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663}
2664
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002665// Test the InsertDtmf on default send stream as callee
2666TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002667 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002668}
2669
2670// Test the InsertDtmf on specified send stream as caller.
2671TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002672 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002673}
2674
2675// Test the InsertDtmf on specified send stream as callee.
2676TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002677 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002678}
2679
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002680TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002681 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002682 EXPECT_CALL(adm_,
2683 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2684 EXPECT_CALL(adm_,
2685 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2686 EXPECT_CALL(adm_,
2687 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002688
solenberg246b8172015-12-08 09:50:23 -08002689 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2690 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002691
solenberg246b8172015-12-08 09:50:23 -08002692 // Nothing set in AudioOptions, so everything should be as default.
2693 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002694 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002695 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002696 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2697 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002698
2699 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002700 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2701 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002702 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002703 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704
2705 // Turn echo cancellation back on, with settings, and make sure
2706 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002707 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2708 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002709 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002710 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002711
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002712 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2713 // control.
solenberg76377c52017-02-21 00:54:31 -08002714 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2715 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002716 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002717 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002718
2719 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002720 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2721 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002722 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2723 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2724 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002725 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002726
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002727 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002728 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2729 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002730 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002731 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002732
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002733 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002734 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2735 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2736 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2737 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002738 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002739 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740
2741 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002742 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2743 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2744 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2745 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002746 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2747 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002748 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749
2750 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002751 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2752 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2753 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2754 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2755 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2756 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2757 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002758 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2759 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2760 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2761 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002762 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002763 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764
solenberg1ac56142015-10-13 03:58:19 -07002765 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002766 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2767 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2768 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2769 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2771 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2772 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002773 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002774}
2775
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002776TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002777 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002778 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002779 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002780 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002781 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002782 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002783 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002784 EXPECT_CALL(adm_,
2785 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2786 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2787 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
2788 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
2789 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002790
kwiberg686a8ef2016-02-26 03:00:35 -08002791 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002792 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002793 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002794 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002795 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002796 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797
2798 // Have to add a stream to make SetSend work.
2799 cricket::StreamParams stream1;
2800 stream1.ssrcs.push_back(1);
2801 channel1->AddSendStream(stream1);
2802 cricket::StreamParams stream2;
2803 stream2.ssrcs.push_back(2);
2804 channel2->AddSendStream(stream2);
2805
2806 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002807 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002808 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2809 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2810 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002811 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2812 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2813 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2814 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2815 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002816 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002817 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002818 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002819 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820
2821 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002822 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002823 parameters_options_no_ns.options.noise_suppression =
2824 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002825 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2826 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2827 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2828 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2829 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002830 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002831 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002832 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2833 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2834 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002835 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002836
2837 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002838 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002839 parameters_options_no_agc.options.auto_gain_control =
2840 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002841 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2842 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2843 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2844 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2845 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002846 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002847 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2848 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2849 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002850 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002851
solenberg76377c52017-02-21 00:54:31 -08002852 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2853 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2854 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2855 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2856 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002857 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858
solenberg76377c52017-02-21 00:54:31 -08002859 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2863 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002864 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002865
solenberg76377c52017-02-21 00:54:31 -08002866 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2867 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2868 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2869 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002871 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002872
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002873 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002874 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2875 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002876 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002877 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002878 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002879 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002880 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2881 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2882 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2883 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002885 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002886 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2887 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2888 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002889 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002890}
2891
wu@webrtc.orgde305012013-10-31 15:40:38 +00002892// This test verifies DSCP settings are properly applied on voice media channel.
2893TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002894 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002895 cricket::FakeNetworkInterface network_interface;
2896 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002897 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002898
solenberg059fb442016-10-26 05:12:24 -07002899 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
2900 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
2901
solenbergbc37fc82016-04-04 09:54:44 -07002902 channel.reset(
2903 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002904 channel->SetInterface(&network_interface);
2905 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2906 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2907
2908 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002909 channel.reset(
2910 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002911 channel->SetInterface(&network_interface);
2912 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2913
2914 // Verify that setting the option to false resets the
2915 // DiffServCodePoint.
2916 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002917 channel.reset(
2918 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002919 channel->SetInterface(&network_interface);
2920 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2921 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2922
2923 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002924}
2925
solenberg1ac56142015-10-13 03:58:19 -07002926TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002927 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928 cricket::WebRtcVoiceMediaChannel* media_channel =
2929 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002930 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002931 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002932 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002933 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2934 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2935 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002936 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002937 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938}
2939
solenberg1ac56142015-10-13 03:58:19 -07002940TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002941 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002942 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002943 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2944 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2945 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002946 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002947 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002948 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2949 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002950 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002951 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002952 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002953 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002954}
2955
solenberg4bac9c52015-10-09 02:32:53 -07002956TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002957 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002958 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002960 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002961 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002962 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2963 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2964 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002965}
2966
solenberg2100c0b2017-03-01 11:29:29 -08002967TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002968 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002969
2970 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002971 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002972 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2973
2974 // Should remember the volume "2" which will be set on new unsignaled streams,
2975 // and also set the gain to 2 on existing unsignaled streams.
2976 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2977 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2978
2979 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2980 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2981 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2982 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
2983 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
2984 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
2985
2986 // Setting gain with SSRC=0 should affect all unsignaled streams.
2987 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07002988 if (kMaxUnsignaledRecvStreams > 1) {
2989 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
2990 }
solenberg2100c0b2017-03-01 11:29:29 -08002991 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
2992
2993 // Setting gain on an individual stream affects only that.
2994 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07002995 if (kMaxUnsignaledRecvStreams > 1) {
2996 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
2997 }
solenberg2100c0b2017-03-01 11:29:29 -08002998 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999}
3000
pbos8fc7fa72015-07-15 08:02:58 -07003001TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003002 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003003 const std::string kSyncLabel = "AvSyncLabel";
3004
solenbergff976312016-03-30 23:28:51 -07003005 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003006 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3007 sp.sync_label = kSyncLabel;
3008 // Creating two channels to make sure that sync label is set properly for both
3009 // the default voice channel and following ones.
3010 EXPECT_TRUE(channel_->AddRecvStream(sp));
3011 sp.ssrcs[0] += 1;
3012 EXPECT_TRUE(channel_->AddRecvStream(sp));
3013
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003014 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003015 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003016 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003017 << "SyncGroup should be set based on sync_label";
3018 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003019 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003020 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003021}
3022
solenberg3a941542015-11-16 07:34:50 -08003023// TODO(solenberg): Remove, once recv streams are configured through Call.
3024// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003025TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003026 // Test that setting the header extensions results in the expected state
3027 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003028 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003029 ssrcs.push_back(223);
3030 ssrcs.push_back(224);
3031
solenbergff976312016-03-30 23:28:51 -07003032 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003033 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003034 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003035 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003036 cricket::StreamParams::CreateLegacy(ssrc)));
3037 }
3038
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003039 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003040 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003041 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003042 EXPECT_NE(nullptr, s);
3043 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3044 }
3045
3046 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003047 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003048 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003049 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003050 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003051 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003052 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003053 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003054 EXPECT_NE(nullptr, s);
3055 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003056 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3057 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003058 for (const auto& s_ext : s_exts) {
3059 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003060 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003061 }
3062 }
3063 }
3064 }
3065
3066 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003067 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003068 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003069 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003070 EXPECT_NE(nullptr, s);
3071 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3072 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003073}
3074
3075TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3076 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003077 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003078 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003079 static const unsigned char kRtcp[] = {
3080 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3081 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3082 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3084 };
jbaucheec21bd2016-03-20 06:15:43 -07003085 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003086
solenbergff976312016-03-30 23:28:51 -07003087 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003088 cricket::WebRtcVoiceMediaChannel* media_channel =
3089 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003090 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003091 EXPECT_TRUE(media_channel->AddRecvStream(
3092 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3093
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003094 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003095 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003096 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003097 EXPECT_EQ(0, s->received_packets());
3098 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3099 EXPECT_EQ(1, s->received_packets());
3100 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3101 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003102}
Minyue2013aec2015-05-13 14:14:42 +02003103
solenberg0a617e22015-10-20 15:49:38 -07003104// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003105// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003106TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003107 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003108 EXPECT_TRUE(AddRecvStream(kSsrcY));
3109 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003110 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003111 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3112 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3113 EXPECT_TRUE(AddRecvStream(kSsrcW));
3114 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003115}
3116
solenberg7602aab2016-11-14 11:30:07 -08003117TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3118 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003119 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003120 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003121 cricket::StreamParams::CreateLegacy(kSsrcY)));
3122 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3123 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3124 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003125 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003126 cricket::StreamParams::CreateLegacy(kSsrcW)));
3127 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3128 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003129}
stefan658910c2015-09-03 05:48:32 -07003130
deadbeef884f5852016-01-15 09:20:04 -08003131TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003132 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003133 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3134 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003135
3136 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003137 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3138 EXPECT_TRUE(AddRecvStream(kSsrcX));
3139 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003140
3141 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003142 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3143 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003144
3145 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003146 channel_->SetRawAudioSink(kSsrcX, nullptr);
3147 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003148}
3149
solenberg2100c0b2017-03-01 11:29:29 -08003150TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003151 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003152 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3153 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003154 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3155 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003156
3157 // Should be able to set a default sink even when no stream exists.
3158 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3159
solenberg2100c0b2017-03-01 11:29:29 -08003160 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3161 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003162 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003163 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003164
3165 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003166 channel_->SetRawAudioSink(kSsrc0, nullptr);
3167 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003168
3169 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003170 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3171 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003172
3173 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003174 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003175 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003176 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3177
3178 // Spawn another unsignaled stream - it should be assigned the default sink
3179 // and the previous unsignaled stream should lose it.
3180 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3181 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3182 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3183 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003184 if (kMaxUnsignaledRecvStreams > 1) {
3185 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3186 }
solenberg2100c0b2017-03-01 11:29:29 -08003187 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3188
3189 // Reset the default sink - the second unsignaled stream should lose it.
3190 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003191 if (kMaxUnsignaledRecvStreams > 1) {
3192 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3193 }
solenberg2100c0b2017-03-01 11:29:29 -08003194 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3195
3196 // Try setting the default sink while two streams exists.
3197 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003198 if (kMaxUnsignaledRecvStreams > 1) {
3199 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3200 }
solenberg2100c0b2017-03-01 11:29:29 -08003201 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3202
3203 // Try setting the sink for the first unsignaled stream using its known SSRC.
3204 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003205 if (kMaxUnsignaledRecvStreams > 1) {
3206 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3207 }
solenberg2100c0b2017-03-01 11:29:29 -08003208 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003209 if (kMaxUnsignaledRecvStreams > 1) {
3210 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3211 }
deadbeef884f5852016-01-15 09:20:04 -08003212}
3213
skvlad7a43d252016-03-22 15:32:27 -07003214// Test that, just like the video channel, the voice channel communicates the
3215// network state to the call.
3216TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003217 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003218
3219 EXPECT_EQ(webrtc::kNetworkUp,
3220 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3221 EXPECT_EQ(webrtc::kNetworkUp,
3222 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3223
3224 channel_->OnReadyToSend(false);
3225 EXPECT_EQ(webrtc::kNetworkDown,
3226 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3227 EXPECT_EQ(webrtc::kNetworkUp,
3228 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3229
3230 channel_->OnReadyToSend(true);
3231 EXPECT_EQ(webrtc::kNetworkUp,
3232 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3233 EXPECT_EQ(webrtc::kNetworkUp,
3234 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3235}
3236
aleloi18e0b672016-10-04 02:45:47 -07003237// Test that playout is still started after changing parameters
3238TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3239 SetupRecvStream();
3240 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003241 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003242
3243 // Changing RTP header extensions will recreate the AudioReceiveStream.
3244 cricket::AudioRecvParameters parameters;
3245 parameters.extensions.push_back(
3246 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3247 channel_->SetRecvParameters(parameters);
3248
solenberg2100c0b2017-03-01 11:29:29 -08003249 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003250}
3251
stefan658910c2015-09-03 05:48:32 -07003252// Tests that the library initializes and shuts down properly.
3253TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003254 // If the VoiceEngine wants to gather available codecs early, that's fine but
3255 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003256 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003257 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003258 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003259 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003260 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003261 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3262 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003263 EXPECT_TRUE(channel != nullptr);
3264 delete channel;
solenbergff976312016-03-30 23:28:51 -07003265}
stefan658910c2015-09-03 05:48:32 -07003266
solenbergff976312016-03-30 23:28:51 -07003267// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003268TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3269 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3270 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3271 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003272 // Return 100ms just in case this function gets called. If we don't,
3273 // we could enter a tight loop since the mock would return 0.
3274 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003275 {
ossuc54071d2016-08-17 02:45:41 -07003276 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003277 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003278 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003279 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003280 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003281 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3282 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3283 EXPECT_TRUE(channel != nullptr);
3284 delete channel;
3285 }
stefan658910c2015-09-03 05:48:32 -07003286}
3287
ossu20a4b3f2017-04-27 02:08:52 -07003288// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3289TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003290 // TODO(ossu): Why are the payload types of codecs with non-static payload
3291 // type assignments checked here? It shouldn't really matter.
3292 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003293 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003294 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003295 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3296 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3297 (clockrate == 0 || codec.clockrate == clockrate);
3298 };
3299 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003300 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003301 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003302 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003303 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003304 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003305 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003306 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003307 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003308 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003309 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003310 EXPECT_EQ(126, codec.id);
3311 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3312 // Remove these checks once both send and receive side assigns payload types
3313 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003314 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003315 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003316 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003317 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003318 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003319 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003320 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003321 EXPECT_EQ(111, codec.id);
3322 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3323 EXPECT_EQ("10", codec.params.find("minptime")->second);
3324 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3325 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003326 }
3327 }
stefan658910c2015-09-03 05:48:32 -07003328}
3329
3330// Tests that VoE supports at least 32 channels
3331TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003332 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003333 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003334 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003335 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003336 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003337
3338 cricket::VoiceMediaChannel* channels[32];
3339 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003340 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003341 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3342 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003343 if (!channel)
3344 break;
stefan658910c2015-09-03 05:48:32 -07003345 channels[num_channels++] = channel;
3346 }
3347
tfarina5237aaf2015-11-10 23:44:30 -08003348 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003349 EXPECT_EQ(expected, num_channels);
3350
3351 while (num_channels > 0) {
3352 delete channels[--num_channels];
3353 }
stefan658910c2015-09-03 05:48:32 -07003354}
3355
3356// Test that we set our preferred codecs properly.
3357TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003358 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3359 // - Check that our builtin codecs are usable by Channel.
3360 // - The codecs provided by the engine is usable by Channel.
3361 // It does not check that the codecs in the RecvParameters are actually
3362 // what we sent in - though it's probably reasonable to expect so, if
3363 // SetRecvParameters returns true.
3364 // I think it will become clear once audio decoder injection is completed.
3365 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003366 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003367 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003368 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003369 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003370 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3371 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003372 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003373 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003374 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003375}
ossu9def8002017-02-09 05:14:32 -08003376
3377TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3378 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003379 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3380 {48000, 2, 16000, 10000, 20000}};
3381 spec1.info.allow_comfort_noise = false;
3382 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003383 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003384 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3385 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003386 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003387 specs.push_back(webrtc::AudioCodecSpec{
3388 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3389 {16000, 1, 13300}});
3390 specs.push_back(
3391 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3392 specs.push_back(
3393 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003394
3395 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3396 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3397 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3398 .WillOnce(Return(specs));
3399
3400 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3401 auto codecs = engine.recv_codecs();
3402 EXPECT_EQ(11, codecs.size());
3403
3404 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3405 // check the actual values safely, to provide better test results.
3406 auto get_codec =
3407 [&codecs](size_t index) -> const cricket::AudioCodec& {
3408 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3409 if (codecs.size() > index)
3410 return codecs[index];
3411 return missing_codec;
3412 };
3413
3414 // Ensure the general codecs are generated first and in order.
3415 for (size_t i = 0; i != specs.size(); ++i) {
3416 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3417 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3418 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3419 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3420 }
3421
3422 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003423 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003424 auto find_codec =
3425 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3426 for (size_t i = 0; i != codecs.size(); ++i) {
3427 const cricket::AudioCodec& codec = codecs[i];
3428 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3429 codec.clockrate == format.clockrate_hz &&
3430 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003431 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003432 }
3433 }
3434 return -1;
3435 };
3436
3437 // Ensure all supplementary codecs are generated last. Their internal ordering
3438 // is not important.
3439 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3440 const int num_specs = static_cast<int>(specs.size());
3441 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3442 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3443 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3444 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3445 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3446 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3447 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3448}