blob: 334e63fab101d391a2a10d2b4394880cb5f93a6c [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"
ossueb1fde42017-05-02 06:46:30 -070014#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
ossuf515ab82016-12-07 04:52:58 -080015#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070016#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080017#include "webrtc/media/base/fakemediaengine.h"
18#include "webrtc/media/base/fakenetworkinterface.h"
19#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080020#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/fakewebrtccall.h"
22#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
23#include "webrtc/media/engine/webrtcvoiceengine.h"
solenbergbc37fc82016-04-04 09:54:44 -070024#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070025#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080026#include "webrtc/pc/channel.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020027#include "webrtc/rtc_base/arraysize.h"
28#include "webrtc/rtc_base/byteorder.h"
29#include "webrtc/rtc_base/safe_conversions.h"
30#include "webrtc/rtc_base/scoped_ref_ptr.h"
kwiberg087bd342017-02-10 08:15:44 -080031#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080032#include "webrtc/test/gtest.h"
kwiberg37e99fd2017-04-10 05:15:48 -070033#include "webrtc/test/mock_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070034#include "webrtc/test/mock_audio_encoder_factory.h"
solenberg76377c52017-02-21 00:54:31 -080035#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
kwiberg1c07c702017-03-27 07:15:49 -070037using testing::ContainerEq;
solenbergbc37fc82016-04-04 09:54:44 -070038using testing::Return;
39using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000040
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020041namespace {
42
solenberg418b7d32017-06-13 00:38:27 -070043constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
solenbergebb349d2017-03-13 05:46:15 -070044
deadbeef67cf2c12016-04-13 10:07:16 -070045const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
46const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
ossu20a4b3f2017-04-27 02:08:52 -070047const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
deadbeef67cf2c12016-04-13 10:07:16 -070048const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
49const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070050const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
51const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080052const cricket::AudioCodec
53 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
54const cricket::AudioCodec
55 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
56
solenberg2100c0b2017-03-01 11:29:29 -080057const uint32_t kSsrc0 = 0;
58const uint32_t kSsrc1 = 1;
59const uint32_t kSsrcX = 0x99;
60const uint32_t kSsrcY = 0x17;
61const uint32_t kSsrcZ = 0x42;
62const uint32_t kSsrcW = 0x02;
63const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064
solenberg971cab02016-06-14 10:02:41 -070065constexpr int kRtpHistoryMs = 5000;
66
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067class FakeVoEWrapper : public cricket::VoEWrapper {
68 public:
69 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg83862e32017-03-28 05:07:15 -070070 : cricket::VoEWrapper(engine) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071 }
72};
skvlad11a9cbf2016-10-07 11:53:05 -070073
solenberg76377c52017-02-21 00:54:31 -080074class MockTransmitMixer : public webrtc::voe::TransmitMixer {
75 public:
76 MockTransmitMixer() = default;
77 virtual ~MockTransmitMixer() = default;
78
79 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
80};
solenberg9a5f032222017-03-15 06:14:12 -070081
82void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
83 RTC_DCHECK(adm);
84 EXPECT_CALL(*adm, AddRef()).WillOnce(Return(0));
85 EXPECT_CALL(*adm, Release()).WillOnce(Return(0));
86#if !defined(WEBRTC_IOS)
87 EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
88 EXPECT_CALL(*adm, SetRecordingChannel(webrtc::AudioDeviceModule::
89 ChannelType::kChannelBoth)).WillOnce(Return(0));
90#if defined(WEBRTC_WIN)
91 EXPECT_CALL(*adm, SetRecordingDevice(
92 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
93 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
94 .WillOnce(Return(0));
95#else
96 EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
97#endif // #if defined(WEBRTC_WIN)
98 EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
99 EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
100 EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
101 EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
102#if defined(WEBRTC_WIN)
103 EXPECT_CALL(*adm, SetPlayoutDevice(
104 testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
105 webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
106 .WillOnce(Return(0));
107#else
108 EXPECT_CALL(*adm, SetPlayoutDevice(0)).WillOnce(Return(0));
109#endif // #if defined(WEBRTC_WIN)
110 EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
111 EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
112 EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
113#endif // #if !defined(WEBRTC_IOS)
114 EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
115 EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
116 EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
117 EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
118}
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200119} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120
solenbergff976312016-03-30 23:28:51 -0700121// Tests that our stub library "works".
122TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -0700123 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
solenberg9a5f032222017-03-15 06:14:12 -0700124 AdmSetupExpectations(&adm);
peaha9cc40b2017-06-29 08:32:09 -0700125 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm =
126 new rtc::RefCountedObject<
127 StrictMock<webrtc::test::MockAudioProcessing>>();
128 EXPECT_CALL(*apm, ApplyConfig(testing::_));
129 EXPECT_CALL(*apm, SetExtraOptions(testing::_));
130 EXPECT_CALL(*apm, Initialize()).WillOnce(Return(0));
131 EXPECT_CALL(*apm, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800132 StrictMock<MockTransmitMixer> transmit_mixer;
133 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
peaha9cc40b2017-06-29 08:32:09 -0700134 cricket::FakeWebRtcVoiceEngine voe(&transmit_mixer);
solenbergff976312016-03-30 23:28:51 -0700135 EXPECT_FALSE(voe.IsInited());
136 {
ossuc54071d2016-08-17 02:45:41 -0700137 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -0700138 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -0700139 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
ossuc54071d2016-08-17 02:45:41 -0700140 new FakeVoEWrapper(&voe));
deadbeefeb02c032017-06-15 08:29:25 -0700141 engine.Init();
solenbergff976312016-03-30 23:28:51 -0700142 EXPECT_TRUE(voe.IsInited());
143 }
144 EXPECT_FALSE(voe.IsInited());
145}
146
deadbeef884f5852016-01-15 09:20:04 -0800147class FakeAudioSink : public webrtc::AudioSinkInterface {
148 public:
149 void OnData(const Data& audio) override {}
150};
151
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800152class FakeAudioSource : public cricket::AudioSource {
153 void SetSink(Sink* sink) override {}
154};
155
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000156class WebRtcVoiceEngineTestFake : public testing::Test {
157 public:
stefanba4c0e42016-02-04 04:12:24 -0800158 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
159
160 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
peaha9cc40b2017-06-29 08:32:09 -0700161 : apm_(new rtc::RefCountedObject<
162 StrictMock<webrtc::test::MockAudioProcessing>>()),
163 apm_gc_(*apm_->gain_control()),
164 apm_ec_(*apm_->echo_cancellation()),
165 apm_ns_(*apm_->noise_suppression()),
166 apm_vd_(*apm_->voice_detection()),
167 call_(webrtc::Call::Config(&event_log_)),
168 voe_(&transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700169 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800170 // AudioDeviceModule.
solenberg9a5f032222017-03-15 06:14:12 -0700171 AdmSetupExpectations(&adm_);
solenberg76377c52017-02-21 00:54:31 -0800172 // AudioProcessing.
peaha9cc40b2017-06-29 08:32:09 -0700173 EXPECT_CALL(*apm_, ApplyConfig(testing::_));
174 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
175 EXPECT_CALL(*apm_, Initialize()).WillOnce(Return(0));
176 EXPECT_CALL(*apm_, DetachAecDump());
solenberg76377c52017-02-21 00:54:31 -0800177 // Default Options.
178 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
179 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
180 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
181 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
182 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
183 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
184 // Init does not overwrite default AGC config.
185 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
186 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
187 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
188 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
189 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
190 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
ossueb1fde42017-05-02 06:46:30 -0700191 // TODO(kwiberg): We should use mock factories here, but a bunch of
kwibergd32bf752017-01-19 07:03:59 -0800192 // the tests here probe the specific set of codecs provided by the builtin
ossueb1fde42017-05-02 06:46:30 -0700193 // factories. Those tests should probably be moved elsewhere.
194 auto encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
195 auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
196 engine_.reset(new cricket::WebRtcVoiceEngine(&adm_, encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -0700197 decoder_factory, nullptr, apm_,
ossueb1fde42017-05-02 06:46:30 -0700198 new FakeVoEWrapper(&voe_)));
deadbeefeb02c032017-06-15 08:29:25 -0700199 engine_->Init();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200200 send_parameters_.codecs.push_back(kPcmuCodec);
201 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800202 // Default Options.
203 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 }
solenberg8189b022016-06-14 12:13:00 -0700205
solenbergff976312016-03-30 23:28:51 -0700206 bool SetupChannel() {
peaha9cc40b2017-06-29 08:32:09 -0700207 EXPECT_CALL(*apm_, ApplyConfig(testing::_));
208 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700209 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
210 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200211 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000212 }
solenberg8189b022016-06-14 12:13:00 -0700213
solenbergff976312016-03-30 23:28:51 -0700214 bool SetupRecvStream() {
215 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700216 return false;
217 }
solenberg2100c0b2017-03-01 11:29:29 -0800218 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700219 }
solenberg8189b022016-06-14 12:13:00 -0700220
solenbergff976312016-03-30 23:28:51 -0700221 bool SetupSendStream() {
222 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000223 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224 }
solenberg2100c0b2017-03-01 11:29:29 -0800225 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800226 return false;
227 }
peaha9cc40b2017-06-29 08:32:09 -0700228 EXPECT_CALL(*apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800229 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 }
solenberg8189b022016-06-14 12:13:00 -0700231
232 bool AddRecvStream(uint32_t ssrc) {
233 EXPECT_TRUE(channel_);
234 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
235 }
236
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000237 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700238 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700239 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800240 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
241 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700242 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800243 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000244 }
solenberg8189b022016-06-14 12:13:00 -0700245
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700247 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000248 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 }
solenberg8189b022016-06-14 12:13:00 -0700250
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200251 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 }
254
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100255 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
256 const auto* send_stream = call_.GetAudioSendStream(ssrc);
257 EXPECT_TRUE(send_stream);
258 return *send_stream;
259 }
260
deadbeef884f5852016-01-15 09:20:04 -0800261 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
262 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
263 EXPECT_TRUE(recv_stream);
264 return *recv_stream;
265 }
266
solenberg3a941542015-11-16 07:34:50 -0800267 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800268 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800269 }
270
solenberg7add0582015-11-20 09:59:34 -0800271 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800272 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800273 }
274
solenberg059fb442016-10-26 05:12:24 -0700275 void SetSend(bool enable) {
276 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700277 if (enable) {
278 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
279 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
280 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
peaha9cc40b2017-06-29 08:32:09 -0700281 EXPECT_CALL(*apm_, ApplyConfig(testing::_));
282 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700283 }
solenberg059fb442016-10-26 05:12:24 -0700284 channel_->SetSend(enable);
285 }
286
287 void SetSendParameters(const cricket::AudioSendParameters& params) {
peaha9cc40b2017-06-29 08:32:09 -0700288 EXPECT_CALL(*apm_, ApplyConfig(testing::_));
289 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
solenberg059fb442016-10-26 05:12:24 -0700290 ASSERT_TRUE(channel_);
291 EXPECT_TRUE(channel_->SetSendParameters(params));
292 }
293
minyue6b825df2016-10-31 04:08:32 -0700294 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
295 const cricket::AudioOptions* options = nullptr) {
peaha9cc40b2017-06-29 08:32:09 -0700296 EXPECT_CALL(*apm_, set_output_will_be_muted(!enable));
solenberg059fb442016-10-26 05:12:24 -0700297 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700298 if (enable && options) {
peaha9cc40b2017-06-29 08:32:09 -0700299 EXPECT_CALL(*apm_, ApplyConfig(testing::_));
300 EXPECT_CALL(*apm_, SetExtraOptions(testing::_));
minyue6b825df2016-10-31 04:08:32 -0700301 }
302 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700303 }
304
solenbergffbbcac2016-11-17 05:25:37 -0800305 void TestInsertDtmf(uint32_t ssrc, bool caller,
306 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700307 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000308 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700309 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000310 // send stream.
311 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800312 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000313 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000314
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700316 SetSendParameters(send_parameters_);
317 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800319 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800320 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700321 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000323
324 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700325 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800326 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000327 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800328 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000329 }
330
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800332 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100334 // Test send.
335 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800336 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100337 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800338 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800339 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800340 EXPECT_EQ(codec.id, telephone_event.payload_type);
341 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100342 EXPECT_EQ(2, telephone_event.event_code);
343 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344 }
345
346 // Test that send bandwidth is set correctly.
347 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000348 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
349 // |expected_result| is the expected result from SetMaxSendBandwidth().
350 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700351 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
352 int max_bitrate,
353 bool expected_result,
354 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200355 cricket::AudioSendParameters parameters;
356 parameters.codecs.push_back(codec);
357 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700358 if (expected_result) {
359 SetSendParameters(parameters);
360 } else {
361 EXPECT_FALSE(channel_->SetSendParameters(parameters));
362 }
solenberg2100c0b2017-03-01 11:29:29 -0800363 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 }
365
skvlade0d46372016-04-07 22:59:22 -0700366 // Sets the per-stream maximum bitrate limit for the specified SSRC.
367 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700368 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700369 EXPECT_EQ(1UL, parameters.encodings.size());
370
deadbeefe702b302017-02-04 12:09:01 -0800371 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700372 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700373 }
374
solenberg059fb442016-10-26 05:12:24 -0700375 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700376 cricket::AudioSendParameters send_parameters;
377 send_parameters.codecs.push_back(codec);
378 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700379 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700380 }
381
ossu20a4b3f2017-04-27 02:08:52 -0700382 void CheckSendCodecBitrate(int32_t ssrc,
383 const char expected_name[],
384 int expected_bitrate) {
385 const auto& spec = GetSendStreamConfig(ssrc).send_codec_spec;
386 EXPECT_EQ(expected_name, spec->format.name);
387 EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700388 }
389
ossu20a4b3f2017-04-27 02:08:52 -0700390 rtc::Optional<int> GetCodecBitrate(int32_t ssrc) {
391 return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
skvlade0d46372016-04-07 22:59:22 -0700392 }
393
minyue6b825df2016-10-31 04:08:32 -0700394 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
395 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
396 }
397
skvlade0d46372016-04-07 22:59:22 -0700398 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
399 int global_max,
400 int stream_max,
401 bool expected_result,
402 int expected_codec_bitrate) {
403 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800404 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700405
406 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700407 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800408 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700409
410 // Verify that reading back the parameters gives results
411 // consistent with the Set() result.
412 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800413 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700414 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
415 EXPECT_EQ(expected_result ? stream_max : -1,
416 resulting_parameters.encodings[0].max_bitrate_bps);
417
418 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800419 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700420 }
421
stefan13f1a0a2016-11-30 07:22:58 -0800422 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
423 int expected_min_bitrate_bps,
424 const char* start_bitrate_kbps,
425 int expected_start_bitrate_bps,
426 const char* max_bitrate_kbps,
427 int expected_max_bitrate_bps) {
428 EXPECT_TRUE(SetupSendStream());
429 auto& codecs = send_parameters_.codecs;
430 codecs.clear();
431 codecs.push_back(kOpusCodec);
432 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
433 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
434 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
435 SetSendParameters(send_parameters_);
436
437 EXPECT_EQ(expected_min_bitrate_bps,
438 call_.GetConfig().bitrate_config.min_bitrate_bps);
439 EXPECT_EQ(expected_start_bitrate_bps,
440 call_.GetConfig().bitrate_config.start_bitrate_bps);
441 EXPECT_EQ(expected_max_bitrate_bps,
442 call_.GetConfig().bitrate_config.max_bitrate_bps);
443 }
444
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000445 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700446 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000447
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000448 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800449 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000450
451 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700452 send_parameters_.extensions.push_back(
453 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700454 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800455 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000456
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000457 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200458 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700459 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800460 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000461
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000462 // Ensure extension is set properly.
463 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700464 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700465 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800466 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
467 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
468 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000469
solenberg7add0582015-11-20 09:59:34 -0800470 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000471 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800472 cricket::StreamParams::CreateLegacy(kSsrcY)));
473 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
474 call_.GetAudioSendStream(kSsrcY));
475 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
476 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
477 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000478
479 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200480 send_parameters_.codecs.push_back(kPcmuCodec);
481 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700482 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800483 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
484 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485 }
486
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000487 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700488 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000489
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000490 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800491 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000492
493 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700494 recv_parameters_.extensions.push_back(
495 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800496 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800497 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000498
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000499 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800500 recv_parameters_.extensions.clear();
501 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800502 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000503
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000504 // Ensure extension is set properly.
505 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700506 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800507 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800508 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
509 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
510 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000511
solenberg7add0582015-11-20 09:59:34 -0800512 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800513 EXPECT_TRUE(AddRecvStream(kSsrcY));
514 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
515 call_.GetAudioReceiveStream(kSsrcY));
516 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
517 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
518 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000519
520 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800521 recv_parameters_.extensions.clear();
522 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800523 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
524 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000525 }
526
solenberg85a04962015-10-27 03:35:21 -0700527 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
528 webrtc::AudioSendStream::Stats stats;
529 stats.local_ssrc = 12;
530 stats.bytes_sent = 345;
531 stats.packets_sent = 678;
532 stats.packets_lost = 9012;
533 stats.fraction_lost = 34.56f;
534 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800535 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700536 stats.ext_seqnum = 789;
537 stats.jitter_ms = 12;
538 stats.rtt_ms = 345;
539 stats.audio_level = 678;
540 stats.aec_quality_min = 9.01f;
541 stats.echo_delay_median_ms = 234;
542 stats.echo_delay_std_ms = 567;
543 stats.echo_return_loss = 890;
544 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700545 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800546 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700547 stats.typing_noise_detected = true;
548 return stats;
549 }
550 void SetAudioSendStreamStats() {
551 for (auto* s : call_.GetAudioSendStreams()) {
552 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200553 }
solenberg85a04962015-10-27 03:35:21 -0700554 }
solenberg566ef242015-11-06 15:34:49 -0800555 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
556 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700557 const auto stats = GetAudioSendStreamStats();
558 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
559 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
560 EXPECT_EQ(info.packets_sent, stats.packets_sent);
561 EXPECT_EQ(info.packets_lost, stats.packets_lost);
562 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
563 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800564 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700565 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
566 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
567 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
568 EXPECT_EQ(info.audio_level, stats.audio_level);
569 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
570 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
571 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
572 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
573 EXPECT_EQ(info.echo_return_loss_enhancement,
574 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700575 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800576 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
577 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800578 EXPECT_EQ(info.typing_noise_detected,
579 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700580 }
581
582 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
583 webrtc::AudioReceiveStream::Stats stats;
584 stats.remote_ssrc = 123;
585 stats.bytes_rcvd = 456;
586 stats.packets_rcvd = 768;
587 stats.packets_lost = 101;
588 stats.fraction_lost = 23.45f;
589 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800590 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700591 stats.ext_seqnum = 678;
592 stats.jitter_ms = 901;
593 stats.jitter_buffer_ms = 234;
594 stats.jitter_buffer_preferred_ms = 567;
595 stats.delay_estimate_ms = 890;
596 stats.audio_level = 1234;
597 stats.expand_rate = 5.67f;
598 stats.speech_expand_rate = 8.90f;
599 stats.secondary_decoded_rate = 1.23f;
600 stats.accelerate_rate = 4.56f;
601 stats.preemptive_expand_rate = 7.89f;
602 stats.decoding_calls_to_silence_generator = 12;
603 stats.decoding_calls_to_neteq = 345;
604 stats.decoding_normal = 67890;
605 stats.decoding_plc = 1234;
606 stats.decoding_cng = 5678;
607 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700608 stats.decoding_muted_output = 3456;
609 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200610 return stats;
611 }
612 void SetAudioReceiveStreamStats() {
613 for (auto* s : call_.GetAudioReceiveStreams()) {
614 s->SetStats(GetAudioReceiveStreamStats());
615 }
616 }
617 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700618 const auto stats = GetAudioReceiveStreamStats();
619 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
620 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
621 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
622 EXPECT_EQ(info.packets_lost, stats.packets_lost);
623 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
624 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800625 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700626 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
627 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
628 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200629 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700630 stats.jitter_buffer_preferred_ms);
631 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
632 EXPECT_EQ(info.audio_level, stats.audio_level);
633 EXPECT_EQ(info.expand_rate, stats.expand_rate);
634 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
635 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
636 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
637 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200638 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700639 stats.decoding_calls_to_silence_generator);
640 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
641 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
642 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
643 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
644 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700645 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700646 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200647 }
hbos1acfbd22016-11-17 23:43:29 -0800648 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
649 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
650 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
651 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
652 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
653 codec.ToCodecParameters());
654 }
655 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
656 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
657 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
658 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
659 codec.ToCodecParameters());
660 }
661 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200662
peah8271d042016-11-22 07:24:52 -0800663 bool IsHighPassFilterEnabled() {
664 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
665 }
666
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700668 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
peaha9cc40b2017-06-29 08:32:09 -0700669 rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
solenberg76377c52017-02-21 00:54:31 -0800670 webrtc::test::MockGainControl& apm_gc_;
671 webrtc::test::MockEchoCancellation& apm_ec_;
672 webrtc::test::MockNoiseSuppression& apm_ns_;
673 webrtc::test::MockVoiceDetection& apm_vd_;
674 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700675 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200676 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000677 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700678 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700679 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200680 cricket::AudioSendParameters send_parameters_;
681 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800682 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800683 private:
684 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000685};
686
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687// Tests that we can create and destroy a channel.
688TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700689 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690}
691
solenberg31fec402016-05-06 02:13:12 -0700692// Test that we can add a send stream and that it has the correct defaults.
693TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
694 EXPECT_TRUE(SetupChannel());
695 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800696 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
697 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
698 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700699 EXPECT_EQ("", config.rtp.c_name);
700 EXPECT_EQ(0u, config.rtp.extensions.size());
701 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
702 config.send_transport);
703}
704
705// Test that we can add a receive stream and that it has the correct defaults.
706TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
707 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800708 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700709 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800710 GetRecvStreamConfig(kSsrcX);
711 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700712 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
713 EXPECT_FALSE(config.rtp.transport_cc);
714 EXPECT_EQ(0u, config.rtp.extensions.size());
715 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
716 config.rtcp_send_transport);
717 EXPECT_EQ("", config.sync_group);
718}
719
stefanba4c0e42016-02-04 04:12:24 -0800720TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700721 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800722 bool opus_found = false;
723 for (cricket::AudioCodec codec : codecs) {
724 if (codec.name == "opus") {
725 EXPECT_TRUE(HasTransportCc(codec));
726 opus_found = true;
727 }
728 }
729 EXPECT_TRUE(opus_found);
730}
731
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732// Test that we set our inbound codecs properly, including changing PT.
733TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700734 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200735 cricket::AudioRecvParameters parameters;
736 parameters.codecs.push_back(kIsacCodec);
737 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800738 parameters.codecs.push_back(kTelephoneEventCodec1);
739 parameters.codecs.push_back(kTelephoneEventCodec2);
740 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200741 parameters.codecs[2].id = 126;
742 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800743 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700744 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
745 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
746 {{0, {"PCMU", 8000, 1}},
747 {106, {"ISAC", 16000, 1}},
748 {126, {"telephone-event", 8000, 1}},
749 {107, {"telephone-event", 32000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750}
751
752// Test that we fail to set an unknown inbound codec.
753TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700754 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200755 cricket::AudioRecvParameters parameters;
756 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700757 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200758 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759}
760
761// Test that we fail if we have duplicate types in the inbound list.
762TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700763 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200764 cricket::AudioRecvParameters parameters;
765 parameters.codecs.push_back(kIsacCodec);
766 parameters.codecs.push_back(kCn16000Codec);
767 parameters.codecs[1].id = kIsacCodec.id;
768 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769}
770
771// Test that we can decode OPUS without stereo parameters.
772TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700773 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200774 cricket::AudioRecvParameters parameters;
775 parameters.codecs.push_back(kIsacCodec);
776 parameters.codecs.push_back(kPcmuCodec);
777 parameters.codecs.push_back(kOpusCodec);
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}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
787// Test that we can decode OPUS with stereo = 0.
788TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
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"] = "0";
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", "0"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802}
803
804// Test that we can decode OPUS with stereo = 1.
805TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
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);
810 parameters.codecs.push_back(kOpusCodec);
811 parameters.codecs[2].params["stereo"] = "1";
812 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800813 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -0700814 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
815 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
816 {{0, {"PCMU", 8000, 1}},
817 {103, {"ISAC", 16000, 1}},
818 {111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that changes to recv codecs are applied to all streams.
822TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700823 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200824 cricket::AudioRecvParameters parameters;
825 parameters.codecs.push_back(kIsacCodec);
826 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800827 parameters.codecs.push_back(kTelephoneEventCodec1);
828 parameters.codecs.push_back(kTelephoneEventCodec2);
829 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 parameters.codecs[2].id = 126;
831 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
kwiberg1c07c702017-03-27 07:15:49 -0700832 for (const auto& ssrc : {kSsrcX, kSsrcY}) {
833 EXPECT_TRUE(AddRecvStream(ssrc));
834 EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
835 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
836 {{0, {"PCMU", 8000, 1}},
837 {106, {"ISAC", 16000, 1}},
838 {126, {"telephone-event", 8000, 1}},
839 {107, {"telephone-event", 32000, 1}}})));
840 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841}
842
843TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700844 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200845 cricket::AudioRecvParameters parameters;
846 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800847 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200848 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849
solenberg2100c0b2017-03-01 11:29:29 -0800850 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800851 ASSERT_EQ(1, dm.count(106));
852 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
855// Test that we can apply the same set of codecs again while playing.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
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);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200863 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864
deadbeefcb383672017-04-26 16:28:42 -0700865 // Remapping a payload type to a different codec should fail.
866 parameters.codecs[0] = kOpusCodec;
867 parameters.codecs[0].id = kIsacCodec.id;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200868 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800869 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870}
871
872// Test that we can add a codec while playing.
873TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700874 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200875 cricket::AudioRecvParameters parameters;
876 parameters.codecs.push_back(kIsacCodec);
877 parameters.codecs.push_back(kCn16000Codec);
878 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700879 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200881 parameters.codecs.push_back(kOpusCodec);
882 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800883 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884}
885
deadbeefcb383672017-04-26 16:28:42 -0700886// Test that we accept adding the same codec with a different payload type.
887// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5847
888TEST_F(WebRtcVoiceEngineTestFake, ChangeRecvCodecPayloadType) {
889 EXPECT_TRUE(SetupRecvStream());
890 cricket::AudioRecvParameters parameters;
891 parameters.codecs.push_back(kIsacCodec);
892 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
893
894 ++parameters.codecs[0].id;
895 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
896}
897
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700899 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000901 // Test that when autobw is enabled, bitrate is kept as the default
902 // value. autobw is enabled for the following tests because the target
903 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904
905 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700906 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907
908 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700909 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910
ossu20a4b3f2017-04-27 02:08:52 -0700911 // opus, default bitrate == 32000 in mono.
912 TestMaxSendBandwidth(kOpusCodec, -1, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913}
914
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000915TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700916 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700919 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
920 // Rates above the max (56000) should be capped.
ossu20a4b3f2017-04-27 02:08:52 -0700921 TestMaxSendBandwidth(kIsacCodec, 100000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700924 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
925 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
926 // Rates above the max (510000) should be capped.
927 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928}
929
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000930TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700931 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000932
933 // Test that we can only set a maximum bitrate for a fixed-rate codec
934 // if it's bigger than the fixed rate.
935
936 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700937 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
938 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
939 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
940 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
941 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
942 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
943 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000944}
945
946TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -0700947 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200948 const int kDesiredBitrate = 128000;
949 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -0700950 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200951 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -0700952 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000953
954 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800955 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000956
solenberg2100c0b2017-03-01 11:29:29 -0800957 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000958}
959
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960// Test that bitrate cannot be set for CBR codecs.
961// Bitrate is ignored if it is higher than the fixed bitrate.
962// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000963TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -0700964 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
966 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -0700967 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800968 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200969
970 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -0700971 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800972 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200973
974 send_parameters_.max_bandwidth_bps = 128;
975 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800976 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977}
978
skvlade0d46372016-04-07 22:59:22 -0700979// Test that the per-stream bitrate limit and the global
980// bitrate limit both apply.
981TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
982 EXPECT_TRUE(SetupSendStream());
983
ossu20a4b3f2017-04-27 02:08:52 -0700984 // opus, default bitrate == 32000.
985 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 32000);
skvlade0d46372016-04-07 22:59:22 -0700986 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
987 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
988 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
989
990 // CBR codecs allow both maximums to exceed the bitrate.
991 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
992 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
993 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
994 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
995
996 // CBR codecs don't allow per stream maximums to be too low.
997 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
998 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
999}
1000
1001// Test that an attempt to set RtpParameters for a stream that does not exist
1002// fails.
1003TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1004 EXPECT_TRUE(SetupChannel());
1005 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001006 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001007 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1008
1009 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001010 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001011}
1012
1013TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001014 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001015 // This test verifies that setting RtpParameters succeeds only if
1016 // the structure contains exactly one encoding.
1017 // TODO(skvlad): Update this test when we start supporting setting parameters
1018 // for each encoding individually.
1019
1020 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001021 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001022 // Two or more encodings should result in failure.
1023 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001024 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001025 // Zero encodings should also fail.
1026 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001027 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001028}
1029
1030// Changing the SSRC through RtpParameters is not allowed.
1031TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1032 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001033 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001034 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001035 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001036}
1037
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001038// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001039// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001040TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1041 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001042 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001043 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001044 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001045 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001046 ASSERT_EQ(1u, parameters.encodings.size());
1047 ASSERT_TRUE(parameters.encodings[0].active);
1048 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001049 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1050 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001051
1052 // Now change it back to active and verify we resume sending.
1053 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001054 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1055 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001056}
1057
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001058// Test that SetRtpSendParameters configures the correct encoding channel for
1059// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001060TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1061 SetupForMultiSendStream();
1062 // Create send streams.
1063 for (uint32_t ssrc : kSsrcs4) {
1064 EXPECT_TRUE(
1065 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1066 }
1067 // Configure one stream to be limited by the stream config, another to be
1068 // limited by the global max, and the third one with no per-stream limit
1069 // (still subject to the global limit).
ossu20a4b3f2017-04-27 02:08:52 -07001070 SetGlobalMaxBitrate(kOpusCodec, 32000);
1071 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 24000));
1072 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 48000));
skvlade0d46372016-04-07 22:59:22 -07001073 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1074
ossu20a4b3f2017-04-27 02:08:52 -07001075 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1076 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[1]));
1077 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001078
1079 // Remove the global cap; the streams should switch to their respective
1080 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001081 SetGlobalMaxBitrate(kOpusCodec, -1);
ossu20a4b3f2017-04-27 02:08:52 -07001082 EXPECT_EQ(24000, GetCodecBitrate(kSsrcs4[0]));
1083 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[1]));
1084 EXPECT_EQ(32000, GetCodecBitrate(kSsrcs4[2]));
skvlade0d46372016-04-07 22:59:22 -07001085}
1086
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001087// Test that GetRtpSendParameters returns the currently configured codecs.
1088TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001089 EXPECT_TRUE(SetupSendStream());
1090 cricket::AudioSendParameters parameters;
1091 parameters.codecs.push_back(kIsacCodec);
1092 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001093 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001094
solenberg2100c0b2017-03-01 11:29:29 -08001095 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001096 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001097 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1098 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001099}
1100
deadbeefcb443432016-12-12 11:12:36 -08001101// Test that GetRtpSendParameters returns an SSRC.
1102TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1103 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001104 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001105 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001106 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001107}
1108
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001109// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001110TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001111 EXPECT_TRUE(SetupSendStream());
1112 cricket::AudioSendParameters parameters;
1113 parameters.codecs.push_back(kIsacCodec);
1114 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001115 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001116
solenberg2100c0b2017-03-01 11:29:29 -08001117 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001118
1119 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001120 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001121
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001122 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001123 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1124 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001125}
1126
minyuececec102017-03-27 13:04:25 -07001127// Test that max_bitrate_bps in send stream config gets updated correctly when
1128// SetRtpSendParameters is called.
1129TEST_F(WebRtcVoiceEngineTestFake, SetRtpSendParameterUpdatesMaxBitrate) {
1130 webrtc::test::ScopedFieldTrials override_field_trials(
1131 "WebRTC-Audio-SendSideBwe/Enabled/");
1132 EXPECT_TRUE(SetupSendStream());
1133 cricket::AudioSendParameters send_parameters;
1134 send_parameters.codecs.push_back(kOpusCodec);
1135 SetSendParameters(send_parameters);
1136
1137 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
1138 // Expect empty on parameters.encodings[0].max_bitrate_bps;
1139 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
1140
1141 constexpr int kMaxBitrateBps = 6000;
1142 rtp_parameters.encodings[0].max_bitrate_bps =
1143 rtc::Optional<int>(kMaxBitrateBps);
1144 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
1145
1146 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
1147 EXPECT_EQ(max_bitrate, kMaxBitrateBps);
1148}
1149
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001150// Test that GetRtpReceiveParameters returns the currently configured codecs.
1151TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1152 EXPECT_TRUE(SetupRecvStream());
1153 cricket::AudioRecvParameters parameters;
1154 parameters.codecs.push_back(kIsacCodec);
1155 parameters.codecs.push_back(kPcmuCodec);
1156 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1157
1158 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001159 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001160 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1161 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1162 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1163}
1164
deadbeefcb443432016-12-12 11:12:36 -08001165// Test that GetRtpReceiveParameters returns an SSRC.
1166TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1167 EXPECT_TRUE(SetupRecvStream());
1168 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001169 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001170 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001171 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001172}
1173
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001174// Test that if we set/get parameters multiple times, we get the same results.
1175TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1176 EXPECT_TRUE(SetupRecvStream());
1177 cricket::AudioRecvParameters parameters;
1178 parameters.codecs.push_back(kIsacCodec);
1179 parameters.codecs.push_back(kPcmuCodec);
1180 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1181
1182 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001183 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001184
1185 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001186 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001187
1188 // ... And this shouldn't change the params returned by
1189 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001190 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1191 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001192}
1193
deadbeef3bc15102017-04-20 19:25:07 -07001194// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
1195// aren't signaled. It should return an empty "RtpEncodingParameters" when
1196// configured to receive an unsignaled stream and no packets have been received
1197// yet, and start returning the SSRC once a packet has been received.
1198TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) {
1199 ASSERT_TRUE(SetupChannel());
1200 // Call necessary methods to configure receiving a default stream as
1201 // soon as it arrives.
1202 cricket::AudioRecvParameters parameters;
1203 parameters.codecs.push_back(kIsacCodec);
1204 parameters.codecs.push_back(kPcmuCodec);
1205 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1206
1207 // Call GetRtpReceiveParameters before configured to receive an unsignaled
1208 // stream. Should return nothing.
1209 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
1210
1211 // Set a sink for an unsignaled stream.
1212 std::unique_ptr<FakeAudioSink> fake_sink(new FakeAudioSink());
1213 // Value of "0" means "unsignaled stream".
1214 channel_->SetRawAudioSink(0, std::move(fake_sink));
1215
1216 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
1217 // in this method means "unsignaled stream".
1218 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
1219 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1220 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1221
1222 // Receive PCMU packet (SSRC=1).
1223 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1224
1225 // The |ssrc| member should still be unset.
1226 rtp_parameters = channel_->GetRtpReceiveParameters(0);
1227 ASSERT_EQ(1u, rtp_parameters.encodings.size());
1228 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
1229}
1230
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001231// Test that we apply codecs properly.
1232TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001233 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001234 cricket::AudioSendParameters parameters;
1235 parameters.codecs.push_back(kIsacCodec);
1236 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001237 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001238 parameters.codecs[0].id = 96;
ossu20a4b3f2017-04-27 02:08:52 -07001239 parameters.codecs[0].bitrate = 22000;
solenberg059fb442016-10-26 05:12:24 -07001240 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001241 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1242 EXPECT_EQ(96, send_codec_spec.payload_type);
1243 EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
1244 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1245 EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
1246 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001247 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001248}
1249
ossu20a4b3f2017-04-27 02:08:52 -07001250// Test that WebRtcVoiceEngine reconfigures, rather than recreates its
1251// AudioSendStream.
1252TEST_F(WebRtcVoiceEngineTestFake, DontRecreateSendStream) {
solenbergff976312016-03-30 23:28:51 -07001253 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001254 cricket::AudioSendParameters parameters;
1255 parameters.codecs.push_back(kIsacCodec);
1256 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001257 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001258 parameters.codecs[0].id = 96;
1259 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001260 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001261 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001262 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001263 // Calling SetSendCodec again with same codec which is already set.
1264 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001265 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001266 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001267}
1268
ossu20a4b3f2017-04-27 02:08:52 -07001269// TODO(ossu): Revisit if these tests need to be here, now that these kinds of
1270// tests should be available in AudioEncoderOpusTest.
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001271
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001272// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001273TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001274 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001275 cricket::AudioSendParameters parameters;
1276 parameters.codecs.push_back(kOpusCodec);
1277 parameters.codecs[0].bitrate = 0;
1278 parameters.codecs[0].clockrate = 50000;
1279 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280}
1281
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001282// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001284 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001285 cricket::AudioSendParameters parameters;
1286 parameters.codecs.push_back(kOpusCodec);
1287 parameters.codecs[0].bitrate = 0;
1288 parameters.codecs[0].channels = 0;
1289 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290}
1291
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001292// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001294 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001295 cricket::AudioSendParameters parameters;
1296 parameters.codecs.push_back(kOpusCodec);
1297 parameters.codecs[0].bitrate = 0;
1298 parameters.codecs[0].channels = 0;
1299 parameters.codecs[0].params["stereo"] = "1";
1300 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001301}
1302
1303// Test that if channel is 1 for opus and there's no stereo, we fail.
1304TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001305 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001306 cricket::AudioSendParameters parameters;
1307 parameters.codecs.push_back(kOpusCodec);
1308 parameters.codecs[0].bitrate = 0;
1309 parameters.codecs[0].channels = 1;
1310 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311}
1312
1313// Test that if channel is 1 for opus and stereo=0, we fail.
1314TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001315 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].channels = 1;
1320 parameters.codecs[0].params["stereo"] = "0";
1321 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322}
1323
1324// Test that if channel is 1 for opus and stereo=1, we fail.
1325TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001326 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kOpusCodec);
1329 parameters.codecs[0].bitrate = 0;
1330 parameters.codecs[0].channels = 1;
1331 parameters.codecs[0].params["stereo"] = "1";
1332 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333}
1334
ossu20a4b3f2017-04-27 02:08:52 -07001335// Test that with bitrate=0 and no stereo, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001336TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001337 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001341 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001342 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343}
1344
ossu20a4b3f2017-04-27 02:08:52 -07001345// Test that with bitrate=0 and stereo=0, bitrate is 32000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001347 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001348 cricket::AudioSendParameters parameters;
1349 parameters.codecs.push_back(kOpusCodec);
1350 parameters.codecs[0].bitrate = 0;
1351 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001352 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001353 CheckSendCodecBitrate(kSsrcX, "opus", 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
ossu20a4b3f2017-04-27 02:08:52 -07001356// Test that with bitrate=invalid and stereo=0, bitrate is 32000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001357TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001358 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001359 cricket::AudioSendParameters parameters;
1360 parameters.codecs.push_back(kOpusCodec);
1361 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001362 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001364 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001365 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001366
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001367 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001368 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001369 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001370}
1371
ossu20a4b3f2017-04-27 02:08:52 -07001372// Test that with bitrate=0 and stereo=1, bitrate is 64000.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001373TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001374 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001375 cricket::AudioSendParameters parameters;
1376 parameters.codecs.push_back(kOpusCodec);
1377 parameters.codecs[0].bitrate = 0;
1378 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001379 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001380 CheckSendCodecBitrate(kSsrcX, "opus", 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381}
1382
ossu20a4b3f2017-04-27 02:08:52 -07001383// Test that with bitrate=invalid and stereo=1, bitrate is 64000.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001384TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001385 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001386 cricket::AudioSendParameters parameters;
1387 parameters.codecs.push_back(kOpusCodec);
1388 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001389 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001391 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001392 CheckSendCodecBitrate(kSsrcX, "opus", 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001393
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001396 CheckSendCodecBitrate(kSsrcX, "opus", 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001397}
1398
ossu20a4b3f2017-04-27 02:08:52 -07001399// Test that with bitrate=N and stereo unset, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001401 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 cricket::AudioSendParameters parameters;
1403 parameters.codecs.push_back(kOpusCodec);
1404 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001405 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001406 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1407 EXPECT_EQ(111, spec.payload_type);
1408 EXPECT_EQ(96000, spec.target_bitrate_bps);
1409 EXPECT_EQ("opus", spec.format.name);
1410 EXPECT_EQ(2, spec.format.num_channels);
1411 EXPECT_EQ(48000, spec.format.clockrate_hz);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412}
1413
ossu20a4b3f2017-04-27 02:08:52 -07001414// Test that with bitrate=N and stereo=0, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001415TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001416 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 cricket::AudioSendParameters parameters;
1418 parameters.codecs.push_back(kOpusCodec);
1419 parameters.codecs[0].bitrate = 30000;
1420 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001421 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001422 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423}
1424
ossu20a4b3f2017-04-27 02:08:52 -07001425// Test that with bitrate=N and without any parameters, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001427 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 cricket::AudioSendParameters parameters;
1429 parameters.codecs.push_back(kOpusCodec);
1430 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001431 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001432 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433}
1434
ossu20a4b3f2017-04-27 02:08:52 -07001435// Test that with bitrate=N and stereo=1, bitrate is N.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001437 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 cricket::AudioSendParameters parameters;
1439 parameters.codecs.push_back(kOpusCodec);
1440 parameters.codecs[0].bitrate = 30000;
1441 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001442 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001443 CheckSendCodecBitrate(kSsrcX, "opus", 30000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001444}
1445
stefan13f1a0a2016-11-30 07:22:58 -08001446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1447 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1448 200000);
1449}
1450
1451TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1452 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1453}
1454
1455TEST_F(WebRtcVoiceEngineTestFake,
1456 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1457 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1458}
1459
1460TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1461 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1462}
1463
1464TEST_F(WebRtcVoiceEngineTestFake,
stefan1ccf73f2017-03-27 03:51:18 -07001465 SetMaxSendBandwidthForAudioDoesntAffectBwe) {
stefan13f1a0a2016-11-30 07:22:58 -08001466 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1467 200000);
stefan1ccf73f2017-03-27 03:51:18 -07001468 send_parameters_.max_bandwidth_bps = 100000;
stefan13f1a0a2016-11-30 07:22:58 -08001469 SetSendParameters(send_parameters_);
1470 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1471 << "Setting max bitrate should keep previous min bitrate.";
1472 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1473 << "Setting max bitrate should not reset start bitrate.";
stefan1ccf73f2017-03-27 03:51:18 -07001474 EXPECT_EQ(200000, call_.GetConfig().bitrate_config.max_bitrate_bps);
stefan13f1a0a2016-11-30 07:22:58 -08001475}
1476
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001477// Test that we can enable NACK with opus as caller.
1478TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001479 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001480 cricket::AudioSendParameters parameters;
1481 parameters.codecs.push_back(kOpusCodec);
1482 parameters.codecs[0].AddFeedbackParam(
1483 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1484 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001485 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001487 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488}
1489
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001490// Test that we can enable NACK with opus as callee.
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001492 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001493 cricket::AudioSendParameters parameters;
1494 parameters.codecs.push_back(kOpusCodec);
1495 parameters.codecs[0].AddFeedbackParam(
1496 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1497 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001498 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001499 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001500 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001501 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001502
1503 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001504 cricket::StreamParams::CreateLegacy(kSsrcX)));
1505 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001506}
1507
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001508// Test that we can enable NACK on receive streams.
1509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001510 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001511 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001512 cricket::AudioSendParameters parameters;
1513 parameters.codecs.push_back(kOpusCodec);
1514 parameters.codecs[0].AddFeedbackParam(
1515 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1516 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001517 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1518 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001519 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001520 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1521 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522}
1523
1524// Test that we can disable NACK.
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001526 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001527 cricket::AudioSendParameters parameters;
1528 parameters.codecs.push_back(kOpusCodec);
1529 parameters.codecs[0].AddFeedbackParam(
1530 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1531 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001532 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001533 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001534
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001535 parameters.codecs.clear();
1536 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001537 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001538 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539}
1540
1541// Test that we can disable NACK on receive streams.
1542TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001543 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001544 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001545 cricket::AudioSendParameters parameters;
1546 parameters.codecs.push_back(kOpusCodec);
1547 parameters.codecs[0].AddFeedbackParam(
1548 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1549 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001550 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001551 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1552 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001553
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001554 parameters.codecs.clear();
1555 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001556 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001557 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1558 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
1561// Test that NACK is enabled on a new receive stream.
1562TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001563 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001564 cricket::AudioSendParameters parameters;
1565 parameters.codecs.push_back(kIsacCodec);
1566 parameters.codecs.push_back(kCn16000Codec);
1567 parameters.codecs[0].AddFeedbackParam(
1568 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1569 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001570 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001571 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572
solenberg2100c0b2017-03-01 11:29:29 -08001573 EXPECT_TRUE(AddRecvStream(kSsrcY));
1574 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1575 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1576 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
stefanba4c0e42016-02-04 04:12:24 -08001579TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001580 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001581 cricket::AudioSendParameters send_parameters;
1582 send_parameters.codecs.push_back(kOpusCodec);
1583 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001584 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001585
1586 cricket::AudioRecvParameters recv_parameters;
1587 recv_parameters.codecs.push_back(kIsacCodec);
1588 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001589 EXPECT_TRUE(AddRecvStream(kSsrcX));
1590 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001591 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001592 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001593
ossudedfd282016-06-14 07:12:39 -07001594 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001595 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001596 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001597 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001598 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001599}
1600
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001601// Test that we can switch back and forth between Opus and ISAC with CN.
1602TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001603 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001604
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001605 cricket::AudioSendParameters opus_parameters;
1606 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001607 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001608 {
ossu20a4b3f2017-04-27 02:08:52 -07001609 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1610 EXPECT_EQ(111, spec.payload_type);
1611 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001612 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001614 cricket::AudioSendParameters isac_parameters;
1615 isac_parameters.codecs.push_back(kIsacCodec);
1616 isac_parameters.codecs.push_back(kCn16000Codec);
1617 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001618 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001619 {
ossu20a4b3f2017-04-27 02:08:52 -07001620 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1621 EXPECT_EQ(103, spec.payload_type);
1622 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001623 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624
solenberg059fb442016-10-26 05:12:24 -07001625 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001626 {
ossu20a4b3f2017-04-27 02:08:52 -07001627 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1628 EXPECT_EQ(111, spec.payload_type);
1629 EXPECT_STRCASEEQ("opus", spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001630 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001631}
1632
1633// Test that we handle various ways of specifying bitrate.
1634TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001635 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001636 cricket::AudioSendParameters parameters;
1637 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
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(32000, 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].bitrate = 0; // bitrate == default
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(103, spec.payload_type);
1651 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1652 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001653 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001654 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001655 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001656 {
ossu20a4b3f2017-04-27 02:08:52 -07001657 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1658 EXPECT_EQ(103, spec.payload_type);
1659 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
1660 EXPECT_EQ(28000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001661 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001663 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001664 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001665 {
ossu20a4b3f2017-04-27 02:08:52 -07001666 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1667 EXPECT_EQ(0, spec.payload_type);
1668 EXPECT_STRCASEEQ("PCMU", spec.format.name.c_str());
1669 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001670 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001672 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001674 {
ossu20a4b3f2017-04-27 02:08:52 -07001675 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1676 EXPECT_EQ(0, spec.payload_type);
1677 EXPECT_STREQ("PCMU", spec.format.name.c_str());
1678 EXPECT_EQ(64000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001679 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 parameters.codecs[0] = kOpusCodec;
1682 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001684 {
ossu20a4b3f2017-04-27 02:08:52 -07001685 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1686 EXPECT_EQ(111, spec.payload_type);
1687 EXPECT_STREQ("opus", spec.format.name.c_str());
1688 EXPECT_EQ(32000, spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -07001689 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001690}
1691
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001692// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07001694 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 cricket::AudioSendParameters parameters;
1696 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001697}
1698
1699// Test that we can set send codecs even with telephone-event codec as the first
1700// one on the list.
1701TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07001702 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001703 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08001704 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001705 parameters.codecs.push_back(kIsacCodec);
1706 parameters.codecs.push_back(kPcmuCodec);
1707 parameters.codecs[0].id = 98; // DTMF
1708 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001709 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001710 const auto& spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1711 EXPECT_EQ(96, spec.payload_type);
1712 EXPECT_STRCASEEQ("ISAC", spec.format.name.c_str());
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001713 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001714}
1715
solenberg31642aa2016-03-14 08:00:37 -07001716// Test that payload type range is limited for telephone-event codec.
1717TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07001718 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07001719 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08001720 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07001721 parameters.codecs.push_back(kIsacCodec);
1722 parameters.codecs[0].id = 0; // DTMF
1723 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001724 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001725 EXPECT_TRUE(channel_->CanInsertDtmf());
1726 parameters.codecs[0].id = 128; // DTMF
1727 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1728 EXPECT_FALSE(channel_->CanInsertDtmf());
1729 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07001730 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07001731 EXPECT_TRUE(channel_->CanInsertDtmf());
1732 parameters.codecs[0].id = -1; // DTMF
1733 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1734 EXPECT_FALSE(channel_->CanInsertDtmf());
1735}
1736
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001737// Test that we can set send codecs even with CN codec as the first
1738// one on the list.
1739TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07001740 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001741 cricket::AudioSendParameters parameters;
1742 parameters.codecs.push_back(kCn16000Codec);
1743 parameters.codecs.push_back(kIsacCodec);
1744 parameters.codecs.push_back(kPcmuCodec);
1745 parameters.codecs[0].id = 98; // wideband CN
1746 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07001747 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001748 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1749 EXPECT_EQ(96, send_codec_spec.payload_type);
1750 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
minyue7a973442016-10-20 03:27:12 -07001751 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752}
1753
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001754// Test that we set VAD and DTMF types correctly as caller.
1755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001756 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 cricket::AudioSendParameters parameters;
1758 parameters.codecs.push_back(kIsacCodec);
1759 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001761 parameters.codecs.push_back(kCn16000Codec);
1762 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001763 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001764 parameters.codecs[0].id = 96;
1765 parameters.codecs[2].id = 97; // wideband CN
1766 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001767 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001768 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1769 EXPECT_EQ(96, send_codec_spec.payload_type);
1770 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1771 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001772 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001773 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774}
1775
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001776// Test that we set VAD and DTMF types correctly as callee.
1777TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001778 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001779 cricket::AudioSendParameters parameters;
1780 parameters.codecs.push_back(kIsacCodec);
1781 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001782 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001783 parameters.codecs.push_back(kCn16000Codec);
1784 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08001785 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001786 parameters.codecs[0].id = 96;
1787 parameters.codecs[2].id = 97; // wideband CN
1788 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001789 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001790 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001791 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001792
ossu20a4b3f2017-04-27 02:08:52 -07001793 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1794 EXPECT_EQ(96, send_codec_spec.payload_type);
1795 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1796 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001797 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001798 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001799}
1800
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801// Test that we only apply VAD if we have a CN codec that matches the
1802// send codec clockrate.
1803TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07001804 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001807 parameters.codecs.push_back(kIsacCodec);
1808 parameters.codecs.push_back(kCn16000Codec);
1809 parameters.codecs[1].id = 97;
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("ISAC", 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(97, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001816 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001818 parameters.codecs[0] = kPcmuCodec;
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("PCMU", 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 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001826 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07001827 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001828 {
ossu20a4b3f2017-04-27 02:08:52 -07001829 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1830 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
1831 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001832 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001833 }
Brave Yao5225dd82015-03-26 07:39:19 +08001834 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001835 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07001836 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001837 {
ossu20a4b3f2017-04-27 02:08:52 -07001838 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1839 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1840 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
minyue7a973442016-10-20 03:27:12 -07001841 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842}
1843
1844// Test that we perform case-insensitive matching of codec names.
1845TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07001846 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001847 cricket::AudioSendParameters parameters;
1848 parameters.codecs.push_back(kIsacCodec);
1849 parameters.codecs.push_back(kPcmuCodec);
1850 parameters.codecs.push_back(kCn16000Codec);
1851 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08001852 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001853 parameters.codecs[0].name = "iSaC";
1854 parameters.codecs[0].id = 96;
1855 parameters.codecs[2].id = 97; // wideband CN
1856 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07001857 SetSendParameters(parameters);
ossu20a4b3f2017-04-27 02:08:52 -07001858 const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
1859 EXPECT_EQ(96, send_codec_spec.payload_type);
1860 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
1861 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07001862 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001863 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864}
1865
stefanba4c0e42016-02-04 04:12:24 -08001866class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
1867 public:
1868 WebRtcVoiceEngineWithSendSideBweTest()
1869 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
1870};
1871
1872TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
1873 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07001874 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08001875 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07001876 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
1877 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
1878 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08001879 extension.id);
1880 return;
1881 }
1882 }
1883 FAIL() << "Transport sequence number extension not in header-extension list.";
1884}
1885
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001886// Test support for audio level header extension.
1887TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001888 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001889}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001890TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001891 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001892}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001893
solenbergd4adce42016-11-17 06:26:52 -08001894// Test support for transport sequence number header extension.
1895TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
1896 TestSetSendRtpHeaderExtensions(
1897 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001898}
solenbergd4adce42016-11-17 06:26:52 -08001899TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
1900 TestSetRecvRtpHeaderExtensions(
1901 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001902}
1903
solenberg1ac56142015-10-13 03:58:19 -07001904// Test that we can create a channel and start sending on it.
1905TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07001906 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001907 SetSendParameters(send_parameters_);
1908 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001909 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07001910 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001911 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001912}
1913
1914// Test that a channel will send if and only if it has a source and is enabled
1915// for sending.
1916TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07001917 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001918 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001919 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07001920 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001921 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
1922 SetAudioSend(kSsrcX, true, &fake_source_);
1923 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
1924 SetAudioSend(kSsrcX, true, nullptr);
1925 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07001926}
1927
solenberg94218532016-06-16 10:53:22 -07001928// Test that a channel is muted/unmuted.
1929TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
1930 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001931 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001932 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1933 SetAudioSend(kSsrcX, true, nullptr);
1934 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
1935 SetAudioSend(kSsrcX, false, nullptr);
1936 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07001937}
1938
solenberg6d6e7c52016-04-13 09:07:30 -07001939// Test that SetSendParameters() does not alter a stream's send state.
1940TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
1941 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001942 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001943
1944 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07001945 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001946 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001947
1948 // Changing RTP header extensions will recreate the AudioSendStream.
1949 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001950 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07001951 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001952 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001953
1954 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07001955 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08001956 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001957
1958 // Changing RTP header extensions will recreate the AudioSendStream.
1959 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001961 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07001962}
1963
solenberg1ac56142015-10-13 03:58:19 -07001964// Test that we can create a channel and start playing out on it.
1965TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07001966 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07001967 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07001968 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08001969 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07001970 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08001971 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001972}
1973
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001974// Test that we can add and remove send streams.
1975TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1976 SetupForMultiSendStream();
1977
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001978 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07001979 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001980
solenbergc96df772015-10-21 13:01:53 -07001981 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001982 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07001983 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07001984 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001985 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001986 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001987 }
tfarina5237aaf2015-11-10 23:44:30 -08001988 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001989
solenbergc96df772015-10-21 13:01:53 -07001990 // Delete the send streams.
1991 for (uint32_t ssrc : kSsrcs4) {
1992 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08001993 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07001994 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001995 }
solenbergc96df772015-10-21 13:01:53 -07001996 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001997}
1998
1999// Test SetSendCodecs correctly configure the codecs in all send streams.
2000TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2001 SetupForMultiSendStream();
2002
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002003 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002004 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002005 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002006 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002007 }
2008
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002009 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002010 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002011 parameters.codecs.push_back(kIsacCodec);
2012 parameters.codecs.push_back(kCn16000Codec);
2013 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002014 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002015
2016 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002017 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002018 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2019 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002020 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2021 EXPECT_STRCASEEQ("ISAC", send_codec_spec.format.name.c_str());
2022 EXPECT_EQ(1, send_codec_spec.format.num_channels);
minyue7a973442016-10-20 03:27:12 -07002023 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002024 }
2025
minyue7a973442016-10-20 03:27:12 -07002026 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002027 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002028 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002029 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002030 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2031 const auto& send_codec_spec =
ossu20a4b3f2017-04-27 02:08:52 -07002032 *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2033 EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
2034 EXPECT_EQ(rtc::Optional<int>(), send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002035 }
2036}
2037
2038// Test we can SetSend on all send streams correctly.
2039TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2040 SetupForMultiSendStream();
2041
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002042 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002043 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002045 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002046 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002047 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002048 }
2049
2050 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002051 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002052 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002053 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002054 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002055 }
2056
2057 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002058 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002059 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002060 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002061 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062 }
2063}
2064
2065// Test we can set the correct statistics on all send streams.
2066TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2067 SetupForMultiSendStream();
2068
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002069 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002070 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002071 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002072 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073 }
solenberg85a04962015-10-27 03:35:21 -07002074
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002075 // Create a receive stream to check that none of the send streams end up in
2076 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002077 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002078
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002079 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002080 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002081 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002082 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002083
solenberg85a04962015-10-27 03:35:21 -07002084 // Check stats for the added streams.
2085 {
2086 cricket::VoiceMediaInfo info;
2087 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002088
solenberg85a04962015-10-27 03:35:21 -07002089 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002090 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002091 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002092 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002093 }
hbos1acfbd22016-11-17 23:43:29 -08002094 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002095
2096 // We have added one receive stream. We should see empty stats.
2097 EXPECT_EQ(info.receivers.size(), 1u);
2098 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002099 }
solenberg1ac56142015-10-13 03:58:19 -07002100
solenberg2100c0b2017-03-01 11:29:29 -08002101 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002102 {
2103 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002104 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002105 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002106 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002107 EXPECT_EQ(0u, info.receivers.size());
2108 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002109
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002110 // Deliver a new packet - a default receive stream should be created and we
2111 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002112 {
2113 cricket::VoiceMediaInfo info;
2114 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2115 SetAudioReceiveStreamStats();
2116 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002117 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002118 EXPECT_EQ(1u, info.receivers.size());
2119 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002120 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002121 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002122}
2123
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002124// Test that we can add and remove receive streams, and do proper send/playout.
2125// We can receive on multiple streams while sending one stream.
2126TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002127 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002128
solenberg1ac56142015-10-13 03:58:19 -07002129 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002130 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002131 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132
solenberg1ac56142015-10-13 03:58:19 -07002133 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002134 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002135 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002136 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137
solenberg1ac56142015-10-13 03:58:19 -07002138 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002139 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140
2141 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002142 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2143 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2144 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145
2146 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002147 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002148 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002149
2150 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002151 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002152 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2153 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002154
aleloi84ef6152016-08-04 05:28:21 -07002155 // Restart playout and make sure recv streams are played out.
2156 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002157 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2158 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002159
aleloi84ef6152016-08-04 05:28:21 -07002160 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002161 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2162 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002163}
2164
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002165// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002166// and start sending on it.
2167TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002168 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002169 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2170 EXPECT_CALL(apm_gc_,
2171 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002172 SetSendParameters(send_parameters_);
2173 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002174 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002175 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002176 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177}
2178
wu@webrtc.org97077a32013-10-25 21:18:33 +00002179TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002180 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002181 EXPECT_CALL(adm_,
2182 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002183 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2184 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002185 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2186 send_parameters_.options.tx_agc_digital_compression_gain =
2187 rtc::Optional<uint16_t>(9);
2188 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2189 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002190 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2191 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2192 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002193 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002194
2195 // Check interaction with adjust_agc_delta. Both should be respected, for
2196 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002197 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002198 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002199 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002200}
2201
wu@webrtc.org97077a32013-10-25 21:18:33 +00002202TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002203 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002204 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2205 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002206 send_parameters_.options.recording_sample_rate =
2207 rtc::Optional<uint32_t>(48000);
2208 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002209 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002210}
2211
minyue6b825df2016-10-31 04:08:32 -07002212TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2213 EXPECT_TRUE(SetupSendStream());
2214 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2215 send_parameters_.options.audio_network_adaptor_config =
2216 rtc::Optional<std::string>("1234");
2217 SetSendParameters(send_parameters_);
2218 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002219 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002220}
2221
2222TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2223 EXPECT_TRUE(SetupSendStream());
2224 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2225 send_parameters_.options.audio_network_adaptor_config =
2226 rtc::Optional<std::string>("1234");
2227 SetSendParameters(send_parameters_);
2228 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002229 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002230 cricket::AudioOptions options;
2231 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002232 SetAudioSend(kSsrcX, true, nullptr, &options);
solenberg2100c0b2017-03-01 11:29:29 -08002233 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002234}
2235
2236TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2237 EXPECT_TRUE(SetupSendStream());
2238 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2239 send_parameters_.options.audio_network_adaptor_config =
2240 rtc::Optional<std::string>("1234");
2241 SetSendParameters(send_parameters_);
2242 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002243 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002244 const int initial_num = call_.GetNumCreatedSendStreams();
2245 cricket::AudioOptions options;
2246 options.audio_network_adaptor = rtc::Optional<bool>();
2247 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2248 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002249 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002250 // AudioSendStream not expected to be recreated.
2251 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2252 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002253 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002254}
2255
michaelt6672b262017-01-11 10:17:59 -08002256class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2257 : public WebRtcVoiceEngineTestFake {
2258 public:
2259 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2260 : WebRtcVoiceEngineTestFake(
2261 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2262 "Enabled/") {}
2263};
2264
2265TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2266 EXPECT_TRUE(SetupSendStream());
2267 cricket::AudioSendParameters parameters;
2268 parameters.codecs.push_back(kOpusCodec);
2269 SetSendParameters(parameters);
2270 const int initial_num = call_.GetNumCreatedSendStreams();
2271 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2272
2273 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2274 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002275 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2276 constexpr int kMinOverheadBps =
2277 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002278
2279 constexpr int kOpusMinBitrateBps = 6000;
2280 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002281 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002282 constexpr int kOpusBitrateFbBps = 32000;
minyuececec102017-03-27 13:04:25 -07002283 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002284 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002285
2286 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2287 parameters.options.audio_network_adaptor_config =
2288 rtc::Optional<std::string>("1234");
2289 SetSendParameters(parameters);
2290
ossu11bfc532017-02-16 05:37:06 -08002291 constexpr int kMinOverheadWithAnaBps =
2292 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002293
2294 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002295 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002296
minyuececec102017-03-27 13:04:25 -07002297 EXPECT_EQ(kOpusBitrateFbBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002298 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002299}
2300
minyuececec102017-03-27 13:04:25 -07002301// This test is similar to
2302// WebRtcVoiceEngineTestFake.SetRtpSendParameterUpdatesMaxBitrate but with an
2303// additional field trial.
2304TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest,
2305 SetRtpSendParameterUpdatesMaxBitrate) {
2306 EXPECT_TRUE(SetupSendStream());
2307 cricket::AudioSendParameters send_parameters;
2308 send_parameters.codecs.push_back(kOpusCodec);
2309 SetSendParameters(send_parameters);
2310
2311 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
2312 // Expect empty on parameters.encodings[0].max_bitrate_bps;
2313 EXPECT_FALSE(rtp_parameters.encodings[0].max_bitrate_bps);
2314
2315 constexpr int kMaxBitrateBps = 6000;
2316 rtp_parameters.encodings[0].max_bitrate_bps =
2317 rtc::Optional<int>(kMaxBitrateBps);
2318 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, rtp_parameters));
2319
2320 const int max_bitrate = GetSendStreamConfig(kSsrcX).max_bitrate_bps;
2321#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
2322 constexpr int kMinOverhead = 3333;
2323#else
2324 constexpr int kMinOverhead = 6666;
2325#endif
2326 EXPECT_EQ(max_bitrate, kMaxBitrateBps + kMinOverhead);
2327}
2328
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002329// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002330// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002331TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002332 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002333 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002334}
2335
2336TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2337 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002338 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002339 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002340 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002341 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002342 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002343 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002344 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002345
solenberg85a04962015-10-27 03:35:21 -07002346 // Check stats for the added streams.
2347 {
2348 cricket::VoiceMediaInfo info;
2349 EXPECT_EQ(true, channel_->GetStats(&info));
2350
2351 // We have added one send stream. We should see the stats we've set.
2352 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002353 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002354 // We have added one receive stream. We should see empty stats.
2355 EXPECT_EQ(info.receivers.size(), 1u);
2356 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2357 }
solenberg1ac56142015-10-13 03:58:19 -07002358
solenberg566ef242015-11-06 15:34:49 -08002359 // Start sending - this affects some reported stats.
2360 {
2361 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002362 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002363 EXPECT_EQ(true, channel_->GetStats(&info));
2364 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002365 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002366 }
2367
solenberg2100c0b2017-03-01 11:29:29 -08002368 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002369 {
2370 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002371 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002372 EXPECT_EQ(true, channel_->GetStats(&info));
2373 EXPECT_EQ(1u, info.senders.size());
2374 EXPECT_EQ(0u, info.receivers.size());
2375 }
solenberg1ac56142015-10-13 03:58:19 -07002376
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002377 // Deliver a new packet - a default receive stream should be created and we
2378 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002379 {
2380 cricket::VoiceMediaInfo info;
2381 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2382 SetAudioReceiveStreamStats();
2383 EXPECT_EQ(true, channel_->GetStats(&info));
2384 EXPECT_EQ(1u, info.senders.size());
2385 EXPECT_EQ(1u, info.receivers.size());
2386 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002387 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002388 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002389}
2390
2391// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002392// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002393TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002394 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002395 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2396 EXPECT_TRUE(AddRecvStream(kSsrcY));
2397 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002398}
2399
2400// Test that the local SSRC is the same on sending and receiving channels if the
2401// receive channel is created before the send channel.
2402TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002403 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002404 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002405 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002406 cricket::StreamParams::CreateLegacy(kSsrcX)));
2407 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2408 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409}
2410
2411// Test that we can properly receive packets.
2412TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002413 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002414 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002415 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002416
2417 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2418 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419}
2420
2421// Test that we can properly receive packets on multiple streams.
2422TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002423 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002424 const uint32_t ssrc1 = 1;
2425 const uint32_t ssrc2 = 2;
2426 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002427 EXPECT_TRUE(AddRecvStream(ssrc1));
2428 EXPECT_TRUE(AddRecvStream(ssrc2));
2429 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002430 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002431 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002432 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002433 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002434 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002435 }
mflodman3d7db262016-04-29 00:57:13 -07002436
2437 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2438 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2439 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2440
2441 EXPECT_EQ(s1.received_packets(), 0);
2442 EXPECT_EQ(s2.received_packets(), 0);
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[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002446 EXPECT_EQ(s1.received_packets(), 0);
2447 EXPECT_EQ(s2.received_packets(), 0);
2448 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002449
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002451 EXPECT_EQ(s1.received_packets(), 1);
2452 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2453 EXPECT_EQ(s2.received_packets(), 0);
2454 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002455
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002456 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002457 EXPECT_EQ(s1.received_packets(), 1);
2458 EXPECT_EQ(s2.received_packets(), 1);
2459 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2460 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002461
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002462 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002463 EXPECT_EQ(s1.received_packets(), 1);
2464 EXPECT_EQ(s2.received_packets(), 1);
2465 EXPECT_EQ(s3.received_packets(), 1);
2466 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002467
mflodman3d7db262016-04-29 00:57:13 -07002468 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2469 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2470 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471}
2472
solenberg2100c0b2017-03-01 11:29:29 -08002473// Test that receiving on an unsignaled stream works (a stream is created).
2474TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002475 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002476 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2477
solenberg7e63ef02015-11-20 00:19:43 -08002478 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002479
2480 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2482 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002483}
2484
solenberg2100c0b2017-03-01 11:29:29 -08002485// Test that receiving N unsignaled stream works (streams will be created), and
2486// that packets are forwarded to them all.
2487TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002489 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002490 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2491
solenberg2100c0b2017-03-01 11:29:29 -08002492 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002493 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002494 rtc::SetBE32(&packet[8], ssrc);
2495 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002496
solenberg2100c0b2017-03-01 11:29:29 -08002497 // Verify we have one new stream for each loop iteration.
2498 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002499 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2500 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002501 }
mflodman3d7db262016-04-29 00:57:13 -07002502
solenberg2100c0b2017-03-01 11:29:29 -08002503 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002504 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002505 rtc::SetBE32(&packet[8], ssrc);
2506 DeliverPacket(packet, sizeof(packet));
2507
solenbergebb349d2017-03-13 05:46:15 -07002508 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002509 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2510 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2511 }
2512
2513 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2514 constexpr uint32_t kAnotherSsrc = 667;
2515 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002516 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002517
2518 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002519 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002520 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002521 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002522 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2523 EXPECT_EQ(2, streams[i]->received_packets());
2524 }
2525 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2526 EXPECT_EQ(1, streams[i]->received_packets());
2527 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002528 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002529}
2530
solenberg2100c0b2017-03-01 11:29:29 -08002531// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002532// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002533TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002534 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002535 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002536 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2537
2538 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002539 const uint32_t signaled_ssrc = 1;
2540 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002541 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002542 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002543 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2544 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002545 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002546
2547 // Note that the first unknown SSRC cannot be 0, because we only support
2548 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002549 const uint32_t unsignaled_ssrc = 7011;
2550 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002551 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002552 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2553 packet, sizeof(packet)));
2554 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2555
2556 DeliverPacket(packet, sizeof(packet));
2557 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2558
2559 rtc::SetBE32(&packet[8], signaled_ssrc);
2560 DeliverPacket(packet, sizeof(packet));
2561 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2562 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002563}
2564
solenberg4904fb62017-02-17 12:01:14 -08002565// Two tests to verify that adding a receive stream with the same SSRC as a
2566// previously added unsignaled stream will only recreate underlying stream
2567// objects if the stream parameters have changed.
2568TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2569 EXPECT_TRUE(SetupChannel());
2570
2571 // Spawn unsignaled stream with SSRC=1.
2572 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2573 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2574 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2575 sizeof(kPcmuFrame)));
2576
2577 // Verify that the underlying stream object in Call is not recreated when a
2578 // stream with SSRC=1 is added.
2579 const auto& streams = call_.GetAudioReceiveStreams();
2580 EXPECT_EQ(1, streams.size());
2581 int audio_receive_stream_id = streams.front()->id();
2582 EXPECT_TRUE(AddRecvStream(1));
2583 EXPECT_EQ(1, streams.size());
2584 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2585}
2586
2587TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2588 EXPECT_TRUE(SetupChannel());
2589
2590 // Spawn unsignaled stream with SSRC=1.
2591 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2592 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2593 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2594 sizeof(kPcmuFrame)));
2595
2596 // Verify that the underlying stream object in Call *is* recreated when a
2597 // stream with SSRC=1 is added, and which has changed stream parameters.
2598 const auto& streams = call_.GetAudioReceiveStreams();
2599 EXPECT_EQ(1, streams.size());
2600 int audio_receive_stream_id = streams.front()->id();
2601 cricket::StreamParams stream_params;
2602 stream_params.ssrcs.push_back(1);
2603 stream_params.sync_label = "sync_label";
2604 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2605 EXPECT_EQ(1, streams.size());
2606 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2607}
2608
solenberg0a617e22015-10-20 15:49:38 -07002609// Test that we properly handle failures to add a receive stream.
2610TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002611 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002612 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002613 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002614}
2615
solenberg0a617e22015-10-20 15:49:38 -07002616// Test that we properly handle failures to add a send stream.
2617TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002618 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002619 voe_.set_fail_create_channel(true);
2620 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2621}
2622
solenberg1ac56142015-10-13 03:58:19 -07002623// Test that AddRecvStream creates new stream.
2624TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002625 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002627 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002628 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629}
2630
2631// Test that after adding a recv stream, we do not decode more codecs than
2632// those previously passed into SetRecvCodecs.
2633TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002634 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002635 cricket::AudioRecvParameters parameters;
2636 parameters.codecs.push_back(kIsacCodec);
2637 parameters.codecs.push_back(kPcmuCodec);
2638 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002639 EXPECT_TRUE(AddRecvStream(kSsrcX));
kwiberg1c07c702017-03-27 07:15:49 -07002640 EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
2641 (ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
2642 {{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002643}
2644
2645// Test that we properly clean up any streams that were added, even if
2646// not explicitly removed.
2647TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002648 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002649 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002650 EXPECT_TRUE(AddRecvStream(1));
2651 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2653 delete channel_;
2654 channel_ = NULL;
2655 EXPECT_EQ(0, voe_.GetNumChannels());
2656}
2657
wu@webrtc.org78187522013-10-07 23:32:02 +00002658TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002659 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002660 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002661}
2662
2663TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002664 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002665 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002666 // Manually delete channel to simulate a failure.
2667 int channel = voe_.GetLastChannel();
2668 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2669 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002670 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002671 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002672 EXPECT_NE(channel, new_channel);
2673 // The last created channel is deleted too.
2674 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002675}
2676
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002677// Test the InsertDtmf on default send stream as caller.
2678TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002679 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002680}
2681
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002682// Test the InsertDtmf on default send stream as callee
2683TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002684 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002685}
2686
2687// Test the InsertDtmf on specified send stream as caller.
2688TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002689 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002690}
2691
2692// Test the InsertDtmf on specified send stream as callee.
2693TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002694 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002695}
2696
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002697TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002698 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002699 EXPECT_CALL(adm_,
2700 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
2701 EXPECT_CALL(adm_,
2702 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
2703 EXPECT_CALL(adm_,
2704 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002705
solenberg246b8172015-12-08 09:50:23 -08002706 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2707 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002708
solenberg246b8172015-12-08 09:50:23 -08002709 // Nothing set in AudioOptions, so everything should be as default.
2710 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07002711 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002712 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08002713 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2714 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715
2716 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08002717 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2718 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002719 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002720 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002721
2722 // Turn echo cancellation back on, with settings, and make sure
2723 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08002724 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2725 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002726 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002727 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002728
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002729 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2730 // control.
solenberg76377c52017-02-21 00:54:31 -08002731 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2732 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002733 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002734 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002735
2736 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08002737 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
2738 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002739 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2740 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2741 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002742 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08002743
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002744 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08002745 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2746 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002747 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002748 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002749
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002750 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08002751 EXPECT_CALL(adm_, SetAGC(false)).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(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002755 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07002756 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757
2758 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08002759 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2760 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2761 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2762 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002763 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2764 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07002765 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766
2767 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08002768 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2769 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2770 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2771 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2772 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2773 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2774 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08002775 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2776 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2777 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2778 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07002779 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08002780 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002781
solenberg1ac56142015-10-13 03:58:19 -07002782 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08002783 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2784 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2785 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2786 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2787 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
2788 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
2789 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07002790 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002791}
2792
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002793TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07002794 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002795 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002796 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002797 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002798 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07002799 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08002800 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07002801 EXPECT_CALL(adm_,
2802 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
2803 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
2804 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
peaha9cc40b2017-06-29 08:32:09 -07002805 EXPECT_CALL(*apm_, ApplyConfig(testing::_)).Times(10);
2806 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07002807
kwiberg686a8ef2016-02-26 03:00:35 -08002808 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07002809 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002810 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08002811 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07002812 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08002813 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002814
2815 // Have to add a stream to make SetSend work.
2816 cricket::StreamParams stream1;
2817 stream1.ssrcs.push_back(1);
2818 channel1->AddSendStream(stream1);
2819 cricket::StreamParams stream2;
2820 stream2.ssrcs.push_back(2);
2821 channel2->AddSendStream(stream2);
2822
2823 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002824 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002825 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2826 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2827 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002828 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2829 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2830 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
2831 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
2832 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002833 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002834 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07002835 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002836 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837
2838 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002839 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002840 parameters_options_no_ns.options.noise_suppression =
2841 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002842 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2843 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2844 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2845 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2846 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002847 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002848 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01002849 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2850 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2851 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002852 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853
2854 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002855 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01002856 parameters_options_no_agc.options.auto_gain_control =
2857 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002858 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2859 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2860 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2861 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2862 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002863 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01002864 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2865 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2866 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07002867 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
solenberg76377c52017-02-21 00:54:31 -08002869 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2870 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2871 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2872 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2873 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002874 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002875
solenberg76377c52017-02-21 00:54:31 -08002876 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
2877 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2878 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2879 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
2880 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002881 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002882
solenberg76377c52017-02-21 00:54:31 -08002883 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2884 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2885 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2886 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2887 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002888 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002890 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002891 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2892 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07002893 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01002894 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07002895 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01002896 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08002897 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
2898 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
2899 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
2900 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
2901 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002902 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01002903 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2904 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2905 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07002906 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907}
2908
wu@webrtc.orgde305012013-10-31 15:40:38 +00002909// This test verifies DSCP settings are properly applied on voice media channel.
2910TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07002911 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08002912 cricket::FakeNetworkInterface network_interface;
2913 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002914 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002915
peaha9cc40b2017-06-29 08:32:09 -07002916 EXPECT_CALL(*apm_, ApplyConfig(testing::_)).Times(3);
2917 EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
solenberg059fb442016-10-26 05:12:24 -07002918
solenbergbc37fc82016-04-04 09:54:44 -07002919 channel.reset(
2920 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002921 channel->SetInterface(&network_interface);
2922 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2923 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2924
2925 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07002926 channel.reset(
2927 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002928 channel->SetInterface(&network_interface);
2929 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
2930
2931 // Verify that setting the option to false resets the
2932 // DiffServCodePoint.
2933 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07002934 channel.reset(
2935 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08002936 channel->SetInterface(&network_interface);
2937 // Default value when DSCP is disabled should be DSCP_DEFAULT.
2938 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
2939
2940 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00002941}
2942
solenberg1ac56142015-10-13 03:58:19 -07002943TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07002944 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945 cricket::WebRtcVoiceMediaChannel* media_channel =
2946 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07002947 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08002948 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07002949 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002950 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
2951 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
2952 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002953 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002954 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002955}
2956
solenberg1ac56142015-10-13 03:58:19 -07002957TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07002958 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002959 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07002960 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2961 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2962 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002963 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07002964 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002965 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
2966 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07002967 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002968 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07002969 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08002970 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002971}
2972
solenberg4bac9c52015-10-09 02:32:53 -07002973TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07002974 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002975 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002976 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08002977 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08002979 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
2980 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
2981 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07002982}
2983
solenberg2100c0b2017-03-01 11:29:29 -08002984TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002985 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002986
2987 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07002988 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08002989 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
2990
2991 // Should remember the volume "2" which will be set on new unsignaled streams,
2992 // and also set the gain to 2 on existing unsignaled streams.
2993 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
2994 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
2995
2996 // Spawn an unsignaled stream by sending a packet - gain should be 2.
2997 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
2998 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
2999 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3000 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3001 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3002
3003 // Setting gain with SSRC=0 should affect all unsignaled streams.
3004 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003005 if (kMaxUnsignaledRecvStreams > 1) {
3006 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3007 }
solenberg2100c0b2017-03-01 11:29:29 -08003008 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3009
3010 // Setting gain on an individual stream affects only that.
3011 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003012 if (kMaxUnsignaledRecvStreams > 1) {
3013 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3014 }
solenberg2100c0b2017-03-01 11:29:29 -08003015 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003016}
3017
pbos8fc7fa72015-07-15 08:02:58 -07003018TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003019 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003020 const std::string kSyncLabel = "AvSyncLabel";
3021
solenbergff976312016-03-30 23:28:51 -07003022 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003023 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3024 sp.sync_label = kSyncLabel;
3025 // Creating two channels to make sure that sync label is set properly for both
3026 // the default voice channel and following ones.
3027 EXPECT_TRUE(channel_->AddRecvStream(sp));
3028 sp.ssrcs[0] += 1;
3029 EXPECT_TRUE(channel_->AddRecvStream(sp));
3030
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003031 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003032 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003033 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003034 << "SyncGroup should be set based on sync_label";
3035 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003036 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003037 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003038}
3039
solenberg3a941542015-11-16 07:34:50 -08003040// TODO(solenberg): Remove, once recv streams are configured through Call.
3041// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003042TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003043 // Test that setting the header extensions results in the expected state
3044 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003045 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003046 ssrcs.push_back(223);
3047 ssrcs.push_back(224);
3048
solenbergff976312016-03-30 23:28:51 -07003049 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003050 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003051 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003052 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003053 cricket::StreamParams::CreateLegacy(ssrc)));
3054 }
3055
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003056 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003057 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003058 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003059 EXPECT_NE(nullptr, s);
3060 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3061 }
3062
3063 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003064 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003065 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003066 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003067 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003068 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003069 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003070 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003071 EXPECT_NE(nullptr, s);
3072 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003073 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3074 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003075 for (const auto& s_ext : s_exts) {
3076 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003077 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003078 }
3079 }
3080 }
3081 }
3082
3083 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003084 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003085 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003086 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003087 EXPECT_NE(nullptr, s);
3088 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3089 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003090}
3091
3092TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3093 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003094 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003095 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003096 static const unsigned char kRtcp[] = {
3097 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3098 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3099 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3101 };
jbaucheec21bd2016-03-20 06:15:43 -07003102 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003103
solenbergff976312016-03-30 23:28:51 -07003104 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003105 cricket::WebRtcVoiceMediaChannel* media_channel =
3106 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003107 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003108 EXPECT_TRUE(media_channel->AddRecvStream(
3109 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3110
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003111 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003112 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003113 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003114 EXPECT_EQ(0, s->received_packets());
3115 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3116 EXPECT_EQ(1, s->received_packets());
3117 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3118 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003119}
Minyue2013aec2015-05-13 14:14:42 +02003120
solenberg0a617e22015-10-20 15:49:38 -07003121// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003122// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003123TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003124 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003125 EXPECT_TRUE(AddRecvStream(kSsrcY));
3126 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003127 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003128 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3129 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3130 EXPECT_TRUE(AddRecvStream(kSsrcW));
3131 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003132}
3133
solenberg7602aab2016-11-14 11:30:07 -08003134TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3135 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003136 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003137 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003138 cricket::StreamParams::CreateLegacy(kSsrcY)));
3139 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3140 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3141 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003142 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003143 cricket::StreamParams::CreateLegacy(kSsrcW)));
3144 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3145 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003146}
stefan658910c2015-09-03 05:48:32 -07003147
deadbeef884f5852016-01-15 09:20:04 -08003148TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003149 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003150 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3151 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003152
3153 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003154 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3155 EXPECT_TRUE(AddRecvStream(kSsrcX));
3156 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003157
3158 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003159 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3160 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003161
3162 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003163 channel_->SetRawAudioSink(kSsrcX, nullptr);
3164 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003165}
3166
solenberg2100c0b2017-03-01 11:29:29 -08003167TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003168 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003169 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3170 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003171 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3172 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003173
3174 // Should be able to set a default sink even when no stream exists.
3175 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3176
solenberg2100c0b2017-03-01 11:29:29 -08003177 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3178 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003179 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003180 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003181
3182 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003183 channel_->SetRawAudioSink(kSsrc0, nullptr);
3184 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003185
3186 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003187 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3188 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003189
3190 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003191 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003192 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003193 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3194
3195 // Spawn another unsignaled stream - it should be assigned the default sink
3196 // and the previous unsignaled stream should lose it.
3197 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3198 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3199 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3200 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003201 if (kMaxUnsignaledRecvStreams > 1) {
3202 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3203 }
solenberg2100c0b2017-03-01 11:29:29 -08003204 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3205
3206 // Reset the default sink - the second unsignaled stream should lose it.
3207 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003208 if (kMaxUnsignaledRecvStreams > 1) {
3209 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3210 }
solenberg2100c0b2017-03-01 11:29:29 -08003211 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3212
3213 // Try setting the default sink while two streams exists.
3214 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003215 if (kMaxUnsignaledRecvStreams > 1) {
3216 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3217 }
solenberg2100c0b2017-03-01 11:29:29 -08003218 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3219
3220 // Try setting the sink for the first unsignaled stream using its known SSRC.
3221 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003222 if (kMaxUnsignaledRecvStreams > 1) {
3223 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3224 }
solenberg2100c0b2017-03-01 11:29:29 -08003225 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003226 if (kMaxUnsignaledRecvStreams > 1) {
3227 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3228 }
deadbeef884f5852016-01-15 09:20:04 -08003229}
3230
skvlad7a43d252016-03-22 15:32:27 -07003231// Test that, just like the video channel, the voice channel communicates the
3232// network state to the call.
3233TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003234 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003235
3236 EXPECT_EQ(webrtc::kNetworkUp,
3237 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3238 EXPECT_EQ(webrtc::kNetworkUp,
3239 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3240
3241 channel_->OnReadyToSend(false);
3242 EXPECT_EQ(webrtc::kNetworkDown,
3243 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3244 EXPECT_EQ(webrtc::kNetworkUp,
3245 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3246
3247 channel_->OnReadyToSend(true);
3248 EXPECT_EQ(webrtc::kNetworkUp,
3249 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3250 EXPECT_EQ(webrtc::kNetworkUp,
3251 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3252}
3253
aleloi18e0b672016-10-04 02:45:47 -07003254// Test that playout is still started after changing parameters
3255TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3256 SetupRecvStream();
3257 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003258 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003259
3260 // Changing RTP header extensions will recreate the AudioReceiveStream.
3261 cricket::AudioRecvParameters parameters;
3262 parameters.extensions.push_back(
3263 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3264 channel_->SetRecvParameters(parameters);
3265
solenberg2100c0b2017-03-01 11:29:29 -08003266 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003267}
3268
stefan658910c2015-09-03 05:48:32 -07003269// Tests that the library initializes and shuts down properly.
3270TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003271 // If the VoiceEngine wants to gather available codecs early, that's fine but
3272 // we never want it to create a decoder at this stage.
peaha9cc40b2017-06-29 08:32:09 -07003273 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3274 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003275 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003276 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003277 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003278 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003279 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003280 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003281 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003282 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3283 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003284 EXPECT_TRUE(channel != nullptr);
3285 delete channel;
solenbergff976312016-03-30 23:28:51 -07003286}
stefan658910c2015-09-03 05:48:32 -07003287
solenbergff976312016-03-30 23:28:51 -07003288// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003289TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3290 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3291 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3292 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003293 // Return 100ms just in case this function gets called. If we don't,
3294 // we could enter a tight loop since the mock would return 0.
3295 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003296 {
peaha9cc40b2017-06-29 08:32:09 -07003297 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3298 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003299 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003300 &adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003301 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003302 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003303 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003304 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003305 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003306 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3307 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3308 EXPECT_TRUE(channel != nullptr);
3309 delete channel;
3310 }
stefan658910c2015-09-03 05:48:32 -07003311}
3312
ossu20a4b3f2017-04-27 02:08:52 -07003313// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3314TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) {
ossuc54071d2016-08-17 02:45:41 -07003315 // TODO(ossu): Why are the payload types of codecs with non-static payload
3316 // type assignments checked here? It shouldn't really matter.
peaha9cc40b2017-06-29 08:32:09 -07003317 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3318 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003319 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003320 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003321 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003322 engine.Init();
solenberg2779bab2016-11-17 04:45:19 -08003323 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
ossu20a4b3f2017-04-27 02:08:52 -07003324 auto is_codec = [&codec](const char* name, int clockrate = 0) {
3325 return STR_CASE_CMP(codec.name.c_str(), name) == 0 &&
3326 (clockrate == 0 || codec.clockrate == clockrate);
3327 };
3328 if (is_codec("CN", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003329 EXPECT_EQ(105, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003330 } else if (is_codec("CN", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003331 EXPECT_EQ(106, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003332 } else if (is_codec("ISAC", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003333 EXPECT_EQ(103, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003334 } else if (is_codec("ISAC", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003335 EXPECT_EQ(104, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003336 } else if (is_codec("G722", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003337 EXPECT_EQ(9, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003338 } else if (is_codec("telephone-event", 8000)) {
solenberg2779bab2016-11-17 04:45:19 -08003339 EXPECT_EQ(126, codec.id);
3340 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3341 // Remove these checks once both send and receive side assigns payload types
3342 // dynamically.
ossu20a4b3f2017-04-27 02:08:52 -07003343 } else if (is_codec("telephone-event", 16000)) {
solenberg2779bab2016-11-17 04:45:19 -08003344 EXPECT_EQ(113, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003345 } else if (is_codec("telephone-event", 32000)) {
solenberg2779bab2016-11-17 04:45:19 -08003346 EXPECT_EQ(112, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003347 } else if (is_codec("telephone-event", 48000)) {
solenberg2779bab2016-11-17 04:45:19 -08003348 EXPECT_EQ(110, codec.id);
ossu20a4b3f2017-04-27 02:08:52 -07003349 } else if (is_codec("opus")) {
solenberg2779bab2016-11-17 04:45:19 -08003350 EXPECT_EQ(111, codec.id);
3351 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3352 EXPECT_EQ("10", codec.params.find("minptime")->second);
3353 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3354 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003355 }
3356 }
stefan658910c2015-09-03 05:48:32 -07003357}
3358
3359// Tests that VoE supports at least 32 channels
3360TEST(WebRtcVoiceEngineTest, Has32Channels) {
peaha9cc40b2017-06-29 08:32:09 -07003361 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3362 webrtc::AudioProcessing::Create();
ossuc54071d2016-08-17 02:45:41 -07003363 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003364 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003365 webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003366 engine.Init();
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)));
stefan658910c2015-09-03 05:48:32 -07003370
3371 cricket::VoiceMediaChannel* channels[32];
3372 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003373 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003374 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3375 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003376 if (!channel)
3377 break;
stefan658910c2015-09-03 05:48:32 -07003378 channels[num_channels++] = channel;
3379 }
3380
tfarina5237aaf2015-11-10 23:44:30 -08003381 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003382 EXPECT_EQ(expected, num_channels);
3383
3384 while (num_channels > 0) {
3385 delete channels[--num_channels];
3386 }
stefan658910c2015-09-03 05:48:32 -07003387}
3388
3389// Test that we set our preferred codecs properly.
3390TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003391 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3392 // - Check that our builtin codecs are usable by Channel.
3393 // - The codecs provided by the engine is usable by Channel.
3394 // It does not check that the codecs in the RecvParameters are actually
3395 // what we sent in - though it's probably reasonable to expect so, if
3396 // SetRecvParameters returns true.
3397 // I think it will become clear once audio decoder injection is completed.
peaha9cc40b2017-06-29 08:32:09 -07003398 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3399 webrtc::AudioProcessing::Create();
ossu29b1a8d2016-06-13 07:34:51 -07003400 cricket::WebRtcVoiceEngine engine(
ossueb1fde42017-05-02 06:46:30 -07003401 nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
peaha9cc40b2017-06-29 08:32:09 -07003402 webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003403 engine.Init();
skvlad11a9cbf2016-10-07 11:53:05 -07003404 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003405 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003406 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003407 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3408 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003409 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003410 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003411 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003412}
ossu9def8002017-02-09 05:14:32 -08003413
3414TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3415 std::vector<webrtc::AudioCodecSpec> specs;
ossua1a040a2017-04-06 10:03:21 -07003416 webrtc::AudioCodecSpec spec1{{"codec1", 48000, 2, {{"param1", "value1"}}},
3417 {48000, 2, 16000, 10000, 20000}};
3418 spec1.info.allow_comfort_noise = false;
3419 spec1.info.supports_network_adaption = true;
ossu9def8002017-02-09 05:14:32 -08003420 specs.push_back(spec1);
ossua1a040a2017-04-06 10:03:21 -07003421 webrtc::AudioCodecSpec spec2{{"codec2", 32000, 1}, {32000, 1, 32000}};
3422 spec2.info.allow_comfort_noise = false;
ossu9def8002017-02-09 05:14:32 -08003423 specs.push_back(spec2);
ossua1a040a2017-04-06 10:03:21 -07003424 specs.push_back(webrtc::AudioCodecSpec{
3425 {"codec3", 16000, 1, {{"param1", "value1b"}, {"param2", "value2"}}},
3426 {16000, 1, 13300}});
3427 specs.push_back(
3428 webrtc::AudioCodecSpec{{"codec4", 8000, 1}, {8000, 1, 64000}});
3429 specs.push_back(
3430 webrtc::AudioCodecSpec{{"codec5", 8000, 2}, {8000, 1, 64000}});
ossu9def8002017-02-09 05:14:32 -08003431
ossueb1fde42017-05-02 06:46:30 -07003432 rtc::scoped_refptr<webrtc::MockAudioEncoderFactory> unused_encoder_factory =
3433 webrtc::MockAudioEncoderFactory::CreateUnusedFactory();
3434 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
ossu9def8002017-02-09 05:14:32 -08003435 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
ossueb1fde42017-05-02 06:46:30 -07003436 EXPECT_CALL(*mock_decoder_factory.get(), GetSupportedDecoders())
ossu9def8002017-02-09 05:14:32 -08003437 .WillOnce(Return(specs));
3438
peaha9cc40b2017-06-29 08:32:09 -07003439 rtc::scoped_refptr<webrtc::AudioProcessing> apm =
3440 webrtc::AudioProcessing::Create();
ossueb1fde42017-05-02 06:46:30 -07003441 cricket::WebRtcVoiceEngine engine(nullptr, unused_encoder_factory,
peaha9cc40b2017-06-29 08:32:09 -07003442 mock_decoder_factory, nullptr, apm);
deadbeefeb02c032017-06-15 08:29:25 -07003443 engine.Init();
ossu9def8002017-02-09 05:14:32 -08003444 auto codecs = engine.recv_codecs();
3445 EXPECT_EQ(11, codecs.size());
3446
3447 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3448 // check the actual values safely, to provide better test results.
3449 auto get_codec =
3450 [&codecs](size_t index) -> const cricket::AudioCodec& {
3451 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3452 if (codecs.size() > index)
3453 return codecs[index];
3454 return missing_codec;
3455 };
3456
3457 // Ensure the general codecs are generated first and in order.
3458 for (size_t i = 0; i != specs.size(); ++i) {
3459 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3460 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3461 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3462 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3463 }
3464
3465 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003466 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003467 auto find_codec =
3468 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3469 for (size_t i = 0; i != codecs.size(); ++i) {
3470 const cricket::AudioCodec& codec = codecs[i];
3471 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3472 codec.clockrate == format.clockrate_hz &&
3473 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003474 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003475 }
3476 }
3477 return -1;
3478 };
3479
3480 // Ensure all supplementary codecs are generated last. Their internal ordering
3481 // is not important.
3482 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3483 const int num_specs = static_cast<int>(specs.size());
3484 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3485 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3486 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3487 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3488 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3489 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3490 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3491}