blob: 5809a08eaafa4ff2157db43f678bb718180ec2b7 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org79047f92014-03-06 23:46:59 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kwiberg686a8ef2016-02-26 03:00:35 -080011#include <memory>
12
kwiberg087bd342017-02-10 08:15:44 -080013#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
tfarina5237aaf2015-11-10 23:44:30 -080014#include "webrtc/base/arraysize.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000015#include "webrtc/base/byteorder.h"
ossubcd88db2017-02-13 07:04:05 -080016#include "webrtc/base/safe_conversions.h"
ossuf515ab82016-12-07 04:52:58 -080017#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070018#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakemediaengine.h"
20#include "webrtc/media/base/fakenetworkinterface.h"
21#include "webrtc/media/base/fakertp.h"
kjellanderf4752772016-03-02 05:42:30 -080022#include "webrtc/media/base/mediaconstants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010023#include "webrtc/media/engine/fakewebrtccall.h"
24#include "webrtc/media/engine/fakewebrtcvoiceengine.h"
25#include "webrtc/media/engine/webrtcvoiceengine.h"
ossu29b1a8d2016-06-13 07:34:51 -070026#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
solenbergbc37fc82016-04-04 09:54:44 -070027#include "webrtc/modules/audio_device/include/mock_audio_device.h"
solenberg059fb442016-10-26 05:12:24 -070028#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwiberg087bd342017-02-10 08:15:44 -080029#include "webrtc/pc/channel.h"
30#include "webrtc/test/field_trial.h"
solenberg76377c52017-02-21 00:54:31 -080031#include "webrtc/test/gtest.h"
32#include "webrtc/voice_engine/transmit_mixer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
solenbergbc37fc82016-04-04 09:54:44 -070034using testing::Return;
35using testing::StrictMock;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000036
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020037namespace {
38
solenbergebb349d2017-03-13 05:46:15 -070039constexpr uint32_t kMaxUnsignaledRecvStreams = 1;
40
deadbeef67cf2c12016-04-13 10:07:16 -070041const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
42const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1);
43const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2);
44const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
45const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
deadbeef67cf2c12016-04-13 10:07:16 -070046const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
47const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
solenberg2779bab2016-11-17 04:45:19 -080048const cricket::AudioCodec
49 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1);
50const cricket::AudioCodec
51 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1);
52
solenberg2100c0b2017-03-01 11:29:29 -080053const uint32_t kSsrc0 = 0;
54const uint32_t kSsrc1 = 1;
55const uint32_t kSsrcX = 0x99;
56const uint32_t kSsrcY = 0x17;
57const uint32_t kSsrcZ = 0x42;
58const uint32_t kSsrcW = 0x02;
59const uint32_t kSsrcs4[] = { 11, 200, 30, 44 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
solenberg971cab02016-06-14 10:02:41 -070061constexpr int kRtpHistoryMs = 5000;
62
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063class FakeVoEWrapper : public cricket::VoEWrapper {
64 public:
65 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
solenberg76377c52017-02-21 00:54:31 -080066 : cricket::VoEWrapper(engine, // base
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067 engine, // codec
solenberg796b8f92017-03-01 17:02:23 -080068 engine) { // hw
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 }
70};
skvlad11a9cbf2016-10-07 11:53:05 -070071
solenberg76377c52017-02-21 00:54:31 -080072class MockTransmitMixer : public webrtc::voe::TransmitMixer {
73 public:
74 MockTransmitMixer() = default;
75 virtual ~MockTransmitMixer() = default;
76
77 MOCK_METHOD1(EnableStereoChannelSwapping, void(bool enable));
78};
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +020079} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080
solenbergff976312016-03-30 23:28:51 -070081// Tests that our stub library "works".
82TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) {
solenbergbc37fc82016-04-04 09:54:44 -070083 StrictMock<webrtc::test::MockAudioDeviceModule> adm;
84 EXPECT_CALL(adm, AddRef()).WillOnce(Return(0));
85 EXPECT_CALL(adm, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -070086 EXPECT_CALL(adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
87 EXPECT_CALL(adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
88 EXPECT_CALL(adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -080089 EXPECT_CALL(adm, SetAGC(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -070090 StrictMock<webrtc::test::MockAudioProcessing> apm;
91 EXPECT_CALL(apm, ApplyConfig(testing::_));
92 EXPECT_CALL(apm, SetExtraOptions(testing::_));
93 EXPECT_CALL(apm, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -080094 StrictMock<MockTransmitMixer> transmit_mixer;
95 EXPECT_CALL(transmit_mixer, EnableStereoChannelSwapping(false));
96 cricket::FakeWebRtcVoiceEngine voe(&apm, &transmit_mixer);
solenbergff976312016-03-30 23:28:51 -070097 EXPECT_FALSE(voe.IsInited());
98 {
ossuc54071d2016-08-17 02:45:41 -070099 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -0800100 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
ossuc54071d2016-08-17 02:45:41 -0700101 new FakeVoEWrapper(&voe));
solenbergff976312016-03-30 23:28:51 -0700102 EXPECT_TRUE(voe.IsInited());
103 }
104 EXPECT_FALSE(voe.IsInited());
105}
106
deadbeef884f5852016-01-15 09:20:04 -0800107class FakeAudioSink : public webrtc::AudioSinkInterface {
108 public:
109 void OnData(const Data& audio) override {}
110};
111
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800112class FakeAudioSource : public cricket::AudioSource {
113 void SetSink(Sink* sink) override {}
114};
115
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116class WebRtcVoiceEngineTestFake : public testing::Test {
117 public:
stefanba4c0e42016-02-04 04:12:24 -0800118 WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {}
119
120 explicit WebRtcVoiceEngineTestFake(const char* field_trials)
solenberg76377c52017-02-21 00:54:31 -0800121 : apm_gc_(*apm_.gain_control()), apm_ec_(*apm_.echo_cancellation()),
122 apm_ns_(*apm_.noise_suppression()), apm_vd_(*apm_.voice_detection()),
123 call_(webrtc::Call::Config(&event_log_)), voe_(&apm_, &transmit_mixer_),
skvlad11a9cbf2016-10-07 11:53:05 -0700124 override_field_trials_(field_trials) {
solenberg76377c52017-02-21 00:54:31 -0800125 // AudioDeviceModule.
solenbergbc37fc82016-04-04 09:54:44 -0700126 EXPECT_CALL(adm_, AddRef()).WillOnce(Return(0));
127 EXPECT_CALL(adm_, Release()).WillOnce(Return(0));
solenberg5b5129a2016-04-08 05:35:48 -0700128 EXPECT_CALL(adm_, BuiltInAECIsAvailable()).WillOnce(Return(false));
129 EXPECT_CALL(adm_, BuiltInAGCIsAvailable()).WillOnce(Return(false));
130 EXPECT_CALL(adm_, BuiltInNSIsAvailable()).WillOnce(Return(false));
solenberg76377c52017-02-21 00:54:31 -0800131 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
132 // AudioProcessing.
solenberg059fb442016-10-26 05:12:24 -0700133 EXPECT_CALL(apm_, ApplyConfig(testing::_));
134 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
135 EXPECT_CALL(apm_, Initialize()).WillOnce(Return(0));
solenberg76377c52017-02-21 00:54:31 -0800136 // Default Options.
137 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
138 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
139 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
140 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
141 EXPECT_CALL(apm_vd_, Enable(true)).WillOnce(Return(0));
142 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(false));
143 // Init does not overwrite default AGC config.
144 EXPECT_CALL(apm_gc_, target_level_dbfs()).WillOnce(Return(1));
145 EXPECT_CALL(apm_gc_, compression_gain_db()).WillRepeatedly(Return(5));
146 EXPECT_CALL(apm_gc_, is_limiter_enabled()).WillRepeatedly(Return(true));
147 EXPECT_CALL(apm_gc_, set_target_level_dbfs(1)).WillOnce(Return(0));
148 EXPECT_CALL(apm_gc_, set_compression_gain_db(5)).WillRepeatedly(Return(0));
149 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
kwibergd32bf752017-01-19 07:03:59 -0800150 // TODO(kwiberg): We should use a mock AudioDecoderFactory, but a bunch of
151 // the tests here probe the specific set of codecs provided by the builtin
152 // factory. Those tests should probably be moved elsewhere.
153 engine_.reset(new cricket::WebRtcVoiceEngine(
154 &adm_, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr,
155 new FakeVoEWrapper(&voe_)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200156 send_parameters_.codecs.push_back(kPcmuCodec);
157 recv_parameters_.codecs.push_back(kPcmuCodec);
solenberg76377c52017-02-21 00:54:31 -0800158 // Default Options.
159 EXPECT_TRUE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 }
solenberg8189b022016-06-14 12:13:00 -0700161
solenbergff976312016-03-30 23:28:51 -0700162 bool SetupChannel() {
solenberg059fb442016-10-26 05:12:24 -0700163 EXPECT_CALL(apm_, ApplyConfig(testing::_));
164 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergbc37fc82016-04-04 09:54:44 -0700165 channel_ = engine_->CreateChannel(&call_, cricket::MediaConfig(),
166 cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200167 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000168 }
solenberg8189b022016-06-14 12:13:00 -0700169
solenbergff976312016-03-30 23:28:51 -0700170 bool SetupRecvStream() {
171 if (!SetupChannel()) {
solenberg1ac56142015-10-13 03:58:19 -0700172 return false;
173 }
solenberg2100c0b2017-03-01 11:29:29 -0800174 return AddRecvStream(kSsrcX);
solenberg1ac56142015-10-13 03:58:19 -0700175 }
solenberg8189b022016-06-14 12:13:00 -0700176
solenbergff976312016-03-30 23:28:51 -0700177 bool SetupSendStream() {
178 if (!SetupChannel()) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000179 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 }
solenberg2100c0b2017-03-01 11:29:29 -0800181 if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX))) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800182 return false;
183 }
solenberg059fb442016-10-26 05:12:24 -0700184 EXPECT_CALL(apm_, set_output_will_be_muted(false));
solenberg2100c0b2017-03-01 11:29:29 -0800185 return channel_->SetAudioSend(kSsrcX, true, nullptr, &fake_source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000186 }
solenberg8189b022016-06-14 12:13:00 -0700187
188 bool AddRecvStream(uint32_t ssrc) {
189 EXPECT_TRUE(channel_);
190 return channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(ssrc));
191 }
192
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000193 void SetupForMultiSendStream() {
solenbergff976312016-03-30 23:28:51 -0700194 EXPECT_TRUE(SetupSendStream());
solenberg0a617e22015-10-20 15:49:38 -0700195 // Remove stream added in Setup.
solenberg2100c0b2017-03-01 11:29:29 -0800196 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
197 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcX));
solenberg0a617e22015-10-20 15:49:38 -0700198 // Verify the channel does not exist.
solenberg2100c0b2017-03-01 11:29:29 -0800199 EXPECT_FALSE(call_.GetAudioSendStream(kSsrcX));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000200 }
solenberg8189b022016-06-14 12:13:00 -0700201
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 void DeliverPacket(const void* data, int len) {
jbaucheec21bd2016-03-20 06:15:43 -0700203 rtc::CopyOnWriteBuffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000204 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
solenberg8189b022016-06-14 12:13:00 -0700206
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200207 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 delete channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 }
210
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100211 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
212 const auto* send_stream = call_.GetAudioSendStream(ssrc);
213 EXPECT_TRUE(send_stream);
214 return *send_stream;
215 }
216
deadbeef884f5852016-01-15 09:20:04 -0800217 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
218 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
219 EXPECT_TRUE(recv_stream);
220 return *recv_stream;
221 }
222
solenberg3a941542015-11-16 07:34:50 -0800223 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800224 return GetSendStream(ssrc).GetConfig();
solenberg3a941542015-11-16 07:34:50 -0800225 }
226
solenberg7add0582015-11-20 09:59:34 -0800227 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800228 return GetRecvStream(ssrc).GetConfig();
solenberg7add0582015-11-20 09:59:34 -0800229 }
230
solenberg059fb442016-10-26 05:12:24 -0700231 void SetSend(bool enable) {
232 ASSERT_TRUE(channel_);
solenbergd53a3f92016-04-14 13:56:37 -0700233 if (enable) {
234 EXPECT_CALL(adm_, RecordingIsInitialized()).WillOnce(Return(false));
235 EXPECT_CALL(adm_, Recording()).WillOnce(Return(false));
236 EXPECT_CALL(adm_, InitRecording()).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -0700237 EXPECT_CALL(apm_, ApplyConfig(testing::_));
238 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
solenbergd53a3f92016-04-14 13:56:37 -0700239 }
solenberg059fb442016-10-26 05:12:24 -0700240 channel_->SetSend(enable);
241 }
242
243 void SetSendParameters(const cricket::AudioSendParameters& params) {
244 EXPECT_CALL(apm_, ApplyConfig(testing::_));
245 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
246 ASSERT_TRUE(channel_);
247 EXPECT_TRUE(channel_->SetSendParameters(params));
248 }
249
minyue6b825df2016-10-31 04:08:32 -0700250 void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source,
251 const cricket::AudioOptions* options = nullptr) {
solenberg059fb442016-10-26 05:12:24 -0700252 EXPECT_CALL(apm_, set_output_will_be_muted(!enable));
253 ASSERT_TRUE(channel_);
minyue6b825df2016-10-31 04:08:32 -0700254 if (enable && options) {
255 EXPECT_CALL(apm_, ApplyConfig(testing::_));
256 EXPECT_CALL(apm_, SetExtraOptions(testing::_));
257 }
258 EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source));
solenbergd53a3f92016-04-14 13:56:37 -0700259 }
260
solenbergffbbcac2016-11-17 05:25:37 -0800261 void TestInsertDtmf(uint32_t ssrc, bool caller,
262 const cricket::AudioCodec& codec) {
solenbergff976312016-03-30 23:28:51 -0700263 EXPECT_TRUE(SetupChannel());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000264 if (caller) {
solenberg0a617e22015-10-20 15:49:38 -0700265 // If this is a caller, local description will be applied and add the
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000266 // send stream.
267 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800268 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000269 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000270
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 // Test we can only InsertDtmf when the other side supports telephone-event.
solenberg059fb442016-10-26 05:12:24 -0700272 SetSendParameters(send_parameters_);
273 SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 EXPECT_FALSE(channel_->CanInsertDtmf());
solenberg1d63dd02015-12-02 12:35:09 -0800275 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
solenbergffbbcac2016-11-17 05:25:37 -0800276 send_parameters_.codecs.push_back(codec);
solenberg059fb442016-10-26 05:12:24 -0700277 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000279
280 if (!caller) {
solenberg0a617e22015-10-20 15:49:38 -0700281 // If this is callee, there's no active send channel yet.
solenberg1d63dd02015-12-02 12:35:09 -0800282 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000283 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800284 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000285 }
286
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287 // Check we fail if the ssrc is invalid.
solenberg1d63dd02015-12-02 12:35:09 -0800288 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100290 // Test send.
291 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
solenberg2100c0b2017-03-01 11:29:29 -0800292 GetSendStream(kSsrcX).GetLatestTelephoneEvent();
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100293 EXPECT_EQ(-1, telephone_event.payload_type);
solenberg1d63dd02015-12-02 12:35:09 -0800294 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
solenberg2100c0b2017-03-01 11:29:29 -0800295 telephone_event = GetSendStream(kSsrcX).GetLatestTelephoneEvent();
solenbergffbbcac2016-11-17 05:25:37 -0800296 EXPECT_EQ(codec.id, telephone_event.payload_type);
297 EXPECT_EQ(codec.clockrate, telephone_event.payload_frequency);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100298 EXPECT_EQ(2, telephone_event.event_code);
299 EXPECT_EQ(123, telephone_event.duration_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300 }
301
302 // Test that send bandwidth is set correctly.
303 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000304 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
305 // |expected_result| is the expected result from SetMaxSendBandwidth().
306 // |expected_bitrate| is the expected audio bitrate afterward.
deadbeef80346142016-04-27 14:17:10 -0700307 void TestMaxSendBandwidth(const cricket::AudioCodec& codec,
308 int max_bitrate,
309 bool expected_result,
310 int expected_bitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200311 cricket::AudioSendParameters parameters;
312 parameters.codecs.push_back(codec);
313 parameters.max_bandwidth_bps = max_bitrate;
solenberg059fb442016-10-26 05:12:24 -0700314 if (expected_result) {
315 SetSendParameters(parameters);
316 } else {
317 EXPECT_FALSE(channel_->SetSendParameters(parameters));
318 }
solenberg2100c0b2017-03-01 11:29:29 -0800319 EXPECT_EQ(expected_bitrate, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 }
321
skvlade0d46372016-04-07 22:59:22 -0700322 // Sets the per-stream maximum bitrate limit for the specified SSRC.
323 bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700324 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
skvlade0d46372016-04-07 22:59:22 -0700325 EXPECT_EQ(1UL, parameters.encodings.size());
326
deadbeefe702b302017-02-04 12:09:01 -0800327 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700328 return channel_->SetRtpSendParameters(ssrc, parameters);
skvlade0d46372016-04-07 22:59:22 -0700329 }
330
solenberg059fb442016-10-26 05:12:24 -0700331 void SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) {
skvlade0d46372016-04-07 22:59:22 -0700332 cricket::AudioSendParameters send_parameters;
333 send_parameters.codecs.push_back(codec);
334 send_parameters.max_bandwidth_bps = bitrate;
solenberg059fb442016-10-26 05:12:24 -0700335 SetSendParameters(send_parameters);
skvlade0d46372016-04-07 22:59:22 -0700336 }
337
minyue7a973442016-10-20 03:27:12 -0700338 void CheckSendCodec(int32_t ssrc,
339 const char expected_name[],
340 int expected_channels,
341 int expected_bitrate) {
342 const auto& codec = GetSendStreamConfig(ssrc).send_codec_spec.codec_inst;
343 EXPECT_STREQ(expected_name, codec.plname);
344 EXPECT_EQ(expected_channels, codec.channels);
345 EXPECT_EQ(expected_bitrate, codec.rate);
346 }
347
348 int GetOpusMaxPlaybackRate(int32_t ssrc) {
349 return GetSendStreamConfig(ssrc).send_codec_spec.opus_max_playback_rate;
350 }
351
352 bool GetOpusDtx(int32_t ssrc) {
353 return GetSendStreamConfig(ssrc).send_codec_spec.enable_opus_dtx;
354 }
355
356 bool GetCodecFec(int32_t ssrc) {
357 return GetSendStreamConfig(ssrc).send_codec_spec.enable_codec_fec;
358 }
359
skvlade0d46372016-04-07 22:59:22 -0700360 int GetCodecBitrate(int32_t ssrc) {
minyue7a973442016-10-20 03:27:12 -0700361 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.rate;
362 }
363
364 int GetCodecPacSize(int32_t ssrc) {
365 return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize;
skvlade0d46372016-04-07 22:59:22 -0700366 }
367
minyue6b825df2016-10-31 04:08:32 -0700368 const rtc::Optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
369 return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
370 }
371
skvlade0d46372016-04-07 22:59:22 -0700372 void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec,
373 int global_max,
374 int stream_max,
375 bool expected_result,
376 int expected_codec_bitrate) {
377 // Clear the bitrate limit from the previous test case.
solenberg2100c0b2017-03-01 11:29:29 -0800378 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcX, -1));
skvlade0d46372016-04-07 22:59:22 -0700379
380 // Attempt to set the requested bitrate limits.
solenberg059fb442016-10-26 05:12:24 -0700381 SetGlobalMaxBitrate(codec, global_max);
solenberg2100c0b2017-03-01 11:29:29 -0800382 EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrcX, stream_max));
skvlade0d46372016-04-07 22:59:22 -0700383
384 // Verify that reading back the parameters gives results
385 // consistent with the Set() result.
386 webrtc::RtpParameters resulting_parameters =
solenberg2100c0b2017-03-01 11:29:29 -0800387 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -0700388 EXPECT_EQ(1UL, resulting_parameters.encodings.size());
389 EXPECT_EQ(expected_result ? stream_max : -1,
390 resulting_parameters.encodings[0].max_bitrate_bps);
391
392 // Verify that the codec settings have the expected bitrate.
solenberg2100c0b2017-03-01 11:29:29 -0800393 EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrcX));
skvlade0d46372016-04-07 22:59:22 -0700394 }
395
stefan13f1a0a2016-11-30 07:22:58 -0800396 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
397 int expected_min_bitrate_bps,
398 const char* start_bitrate_kbps,
399 int expected_start_bitrate_bps,
400 const char* max_bitrate_kbps,
401 int expected_max_bitrate_bps) {
402 EXPECT_TRUE(SetupSendStream());
403 auto& codecs = send_parameters_.codecs;
404 codecs.clear();
405 codecs.push_back(kOpusCodec);
406 codecs[0].params[cricket::kCodecParamMinBitrate] = min_bitrate_kbps;
407 codecs[0].params[cricket::kCodecParamStartBitrate] = start_bitrate_kbps;
408 codecs[0].params[cricket::kCodecParamMaxBitrate] = max_bitrate_kbps;
409 SetSendParameters(send_parameters_);
410
411 EXPECT_EQ(expected_min_bitrate_bps,
412 call_.GetConfig().bitrate_config.min_bitrate_bps);
413 EXPECT_EQ(expected_start_bitrate_bps,
414 call_.GetConfig().bitrate_config.start_bitrate_bps);
415 EXPECT_EQ(expected_max_bitrate_bps,
416 call_.GetConfig().bitrate_config.max_bitrate_bps);
417 }
418
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000419 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700420 EXPECT_TRUE(SetupSendStream());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000421
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000422 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800423 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000424
425 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700426 send_parameters_.extensions.push_back(
427 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg059fb442016-10-26 05:12:24 -0700428 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800429 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000430
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000431 // Ensure extensions stay off with an empty list of headers.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200432 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700433 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800434 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000435
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000436 // Ensure extension is set properly.
437 const int id = 1;
isheriff6f8d6862016-05-26 11:24:55 -0700438 send_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg059fb442016-10-26 05:12:24 -0700439 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800440 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
441 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcX).rtp.extensions[0].uri);
442 EXPECT_EQ(id, GetSendStreamConfig(kSsrcX).rtp.extensions[0].id);
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000443
solenberg7add0582015-11-20 09:59:34 -0800444 // Ensure extension is set properly on new stream.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000445 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -0800446 cricket::StreamParams::CreateLegacy(kSsrcY)));
447 EXPECT_NE(call_.GetAudioSendStream(kSsrcX),
448 call_.GetAudioSendStream(kSsrcY));
449 EXPECT_EQ(1u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
450 EXPECT_EQ(ext, GetSendStreamConfig(kSsrcY).rtp.extensions[0].uri);
451 EXPECT_EQ(id, GetSendStreamConfig(kSsrcY).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000452
453 // Ensure all extensions go back off with an empty list.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200454 send_parameters_.codecs.push_back(kPcmuCodec);
455 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -0700456 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -0800457 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcX).rtp.extensions.size());
458 EXPECT_EQ(0u, GetSendStreamConfig(kSsrcY).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000459 }
460
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000461 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
solenbergff976312016-03-30 23:28:51 -0700462 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000463
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000464 // Ensure extensions are off by default.
solenberg2100c0b2017-03-01 11:29:29 -0800465 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000466
467 // Ensure unknown extensions won't cause an error.
isheriff6f8d6862016-05-26 11:24:55 -0700468 recv_parameters_.extensions.push_back(
469 webrtc::RtpExtension("urn:ietf:params:unknownextention", 1));
solenberg7add0582015-11-20 09:59:34 -0800470 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800471 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000472
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000473 // Ensure extensions stay off with an empty list of headers.
solenberg7add0582015-11-20 09:59:34 -0800474 recv_parameters_.extensions.clear();
475 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800476 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000477
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000478 // Ensure extension is set properly.
479 const int id = 2;
isheriff6f8d6862016-05-26 11:24:55 -0700480 recv_parameters_.extensions.push_back(webrtc::RtpExtension(ext, id));
solenberg7add0582015-11-20 09:59:34 -0800481 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800482 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
483 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].uri);
484 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcX).rtp.extensions[0].id);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000485
solenberg7add0582015-11-20 09:59:34 -0800486 // Ensure extension is set properly on new stream.
solenberg2100c0b2017-03-01 11:29:29 -0800487 EXPECT_TRUE(AddRecvStream(kSsrcY));
488 EXPECT_NE(call_.GetAudioReceiveStream(kSsrcX),
489 call_.GetAudioReceiveStream(kSsrcY));
490 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
491 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].uri);
492 EXPECT_EQ(id, GetRecvStreamConfig(kSsrcY).rtp.extensions[0].id);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000493
494 // Ensure all extensions go back off with an empty list.
solenberg7add0582015-11-20 09:59:34 -0800495 recv_parameters_.extensions.clear();
496 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -0800497 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcX).rtp.extensions.size());
498 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrcY).rtp.extensions.size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000499 }
500
solenberg85a04962015-10-27 03:35:21 -0700501 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
502 webrtc::AudioSendStream::Stats stats;
503 stats.local_ssrc = 12;
504 stats.bytes_sent = 345;
505 stats.packets_sent = 678;
506 stats.packets_lost = 9012;
507 stats.fraction_lost = 34.56f;
508 stats.codec_name = "codec_name_send";
hbos1acfbd22016-11-17 23:43:29 -0800509 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700510 stats.ext_seqnum = 789;
511 stats.jitter_ms = 12;
512 stats.rtt_ms = 345;
513 stats.audio_level = 678;
514 stats.aec_quality_min = 9.01f;
515 stats.echo_delay_median_ms = 234;
516 stats.echo_delay_std_ms = 567;
517 stats.echo_return_loss = 890;
518 stats.echo_return_loss_enhancement = 1234;
ivoc8c63a822016-10-21 04:10:03 -0700519 stats.residual_echo_likelihood = 0.432f;
ivoc4e477a12017-01-15 08:29:46 -0800520 stats.residual_echo_likelihood_recent_max = 0.6f;
solenberg85a04962015-10-27 03:35:21 -0700521 stats.typing_noise_detected = true;
522 return stats;
523 }
524 void SetAudioSendStreamStats() {
525 for (auto* s : call_.GetAudioSendStreams()) {
526 s->SetStats(GetAudioSendStreamStats());
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200527 }
solenberg85a04962015-10-27 03:35:21 -0700528 }
solenberg566ef242015-11-06 15:34:49 -0800529 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
530 bool is_sending) {
solenberg85a04962015-10-27 03:35:21 -0700531 const auto stats = GetAudioSendStreamStats();
532 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
533 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
534 EXPECT_EQ(info.packets_sent, stats.packets_sent);
535 EXPECT_EQ(info.packets_lost, stats.packets_lost);
536 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
537 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800538 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700539 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
540 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
541 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
542 EXPECT_EQ(info.audio_level, stats.audio_level);
543 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
544 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
545 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
546 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
547 EXPECT_EQ(info.echo_return_loss_enhancement,
548 stats.echo_return_loss_enhancement);
ivoc8c63a822016-10-21 04:10:03 -0700549 EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood);
ivoc4e477a12017-01-15 08:29:46 -0800550 EXPECT_EQ(info.residual_echo_likelihood_recent_max,
551 stats.residual_echo_likelihood_recent_max);
solenberg566ef242015-11-06 15:34:49 -0800552 EXPECT_EQ(info.typing_noise_detected,
553 stats.typing_noise_detected && is_sending);
solenberg85a04962015-10-27 03:35:21 -0700554 }
555
556 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
557 webrtc::AudioReceiveStream::Stats stats;
558 stats.remote_ssrc = 123;
559 stats.bytes_rcvd = 456;
560 stats.packets_rcvd = 768;
561 stats.packets_lost = 101;
562 stats.fraction_lost = 23.45f;
563 stats.codec_name = "codec_name_recv";
hbos1acfbd22016-11-17 23:43:29 -0800564 stats.codec_payload_type = rtc::Optional<int>(42);
solenberg85a04962015-10-27 03:35:21 -0700565 stats.ext_seqnum = 678;
566 stats.jitter_ms = 901;
567 stats.jitter_buffer_ms = 234;
568 stats.jitter_buffer_preferred_ms = 567;
569 stats.delay_estimate_ms = 890;
570 stats.audio_level = 1234;
571 stats.expand_rate = 5.67f;
572 stats.speech_expand_rate = 8.90f;
573 stats.secondary_decoded_rate = 1.23f;
574 stats.accelerate_rate = 4.56f;
575 stats.preemptive_expand_rate = 7.89f;
576 stats.decoding_calls_to_silence_generator = 12;
577 stats.decoding_calls_to_neteq = 345;
578 stats.decoding_normal = 67890;
579 stats.decoding_plc = 1234;
580 stats.decoding_cng = 5678;
581 stats.decoding_plc_cng = 9012;
henrik.lundin63489782016-09-20 01:47:12 -0700582 stats.decoding_muted_output = 3456;
583 stats.capture_start_ntp_time_ms = 7890;
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200584 return stats;
585 }
586 void SetAudioReceiveStreamStats() {
587 for (auto* s : call_.GetAudioReceiveStreams()) {
588 s->SetStats(GetAudioReceiveStreamStats());
589 }
590 }
591 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
solenberg85a04962015-10-27 03:35:21 -0700592 const auto stats = GetAudioReceiveStreamStats();
593 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
594 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
595 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
596 EXPECT_EQ(info.packets_lost, stats.packets_lost);
597 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
598 EXPECT_EQ(info.codec_name, stats.codec_name);
hbos1acfbd22016-11-17 23:43:29 -0800599 EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type);
solenberg85a04962015-10-27 03:35:21 -0700600 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
601 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
602 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200603 EXPECT_EQ(info.jitter_buffer_preferred_ms,
solenberg85a04962015-10-27 03:35:21 -0700604 stats.jitter_buffer_preferred_ms);
605 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
606 EXPECT_EQ(info.audio_level, stats.audio_level);
607 EXPECT_EQ(info.expand_rate, stats.expand_rate);
608 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
609 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
610 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
611 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200612 EXPECT_EQ(info.decoding_calls_to_silence_generator,
solenberg85a04962015-10-27 03:35:21 -0700613 stats.decoding_calls_to_silence_generator);
614 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
615 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
616 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
617 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
618 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
henrik.lundin63489782016-09-20 01:47:12 -0700619 EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output);
solenberg85a04962015-10-27 03:35:21 -0700620 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200621 }
hbos1acfbd22016-11-17 23:43:29 -0800622 void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const {
623 EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size());
624 for (const cricket::AudioCodec& codec : send_parameters_.codecs) {
625 ASSERT_EQ(info.send_codecs.count(codec.id), 1U);
626 EXPECT_EQ(info.send_codecs.find(codec.id)->second,
627 codec.ToCodecParameters());
628 }
629 EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size());
630 for (const cricket::AudioCodec& codec : recv_parameters_.codecs) {
631 ASSERT_EQ(info.receive_codecs.count(codec.id), 1U);
632 EXPECT_EQ(info.receive_codecs.find(codec.id)->second,
633 codec.ToCodecParameters());
634 }
635 }
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +0200636
peah8271d042016-11-22 07:24:52 -0800637 bool IsHighPassFilterEnabled() {
638 return engine_->GetApmConfigForTest().high_pass_filter.enabled;
639 }
640
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641 protected:
solenbergbc37fc82016-04-04 09:54:44 -0700642 StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
solenberg059fb442016-10-26 05:12:24 -0700643 StrictMock<webrtc::test::MockAudioProcessing> apm_;
solenberg76377c52017-02-21 00:54:31 -0800644 webrtc::test::MockGainControl& apm_gc_;
645 webrtc::test::MockEchoCancellation& apm_ec_;
646 webrtc::test::MockNoiseSuppression& apm_ns_;
647 webrtc::test::MockVoiceDetection& apm_vd_;
648 StrictMock<MockTransmitMixer> transmit_mixer_;
skvlad11a9cbf2016-10-07 11:53:05 -0700649 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200650 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651 cricket::FakeWebRtcVoiceEngine voe_;
solenbergbc37fc82016-04-04 09:54:44 -0700652 std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
solenbergff976312016-03-30 23:28:51 -0700653 cricket::VoiceMediaChannel* channel_ = nullptr;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200654 cricket::AudioSendParameters send_parameters_;
655 cricket::AudioRecvParameters recv_parameters_;
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800656 FakeAudioSource fake_source_;
stefanba4c0e42016-02-04 04:12:24 -0800657 private:
658 webrtc::test::ScopedFieldTrials override_field_trials_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000659};
660
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661// Tests that we can create and destroy a channel.
662TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
solenbergff976312016-03-30 23:28:51 -0700663 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000664}
665
solenberg31fec402016-05-06 02:13:12 -0700666// Test that we can add a send stream and that it has the correct defaults.
667TEST_F(WebRtcVoiceEngineTestFake, CreateSendStream) {
668 EXPECT_TRUE(SetupChannel());
669 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -0800670 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
671 const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
672 EXPECT_EQ(kSsrcX, config.rtp.ssrc);
solenberg31fec402016-05-06 02:13:12 -0700673 EXPECT_EQ("", config.rtp.c_name);
674 EXPECT_EQ(0u, config.rtp.extensions.size());
675 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
676 config.send_transport);
677}
678
679// Test that we can add a receive stream and that it has the correct defaults.
680TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) {
681 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -0800682 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg31fec402016-05-06 02:13:12 -0700683 const webrtc::AudioReceiveStream::Config& config =
solenberg2100c0b2017-03-01 11:29:29 -0800684 GetRecvStreamConfig(kSsrcX);
685 EXPECT_EQ(kSsrcX, config.rtp.remote_ssrc);
solenberg31fec402016-05-06 02:13:12 -0700686 EXPECT_EQ(0xFA17FA17, config.rtp.local_ssrc);
687 EXPECT_FALSE(config.rtp.transport_cc);
688 EXPECT_EQ(0u, config.rtp.extensions.size());
689 EXPECT_EQ(static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_),
690 config.rtcp_send_transport);
691 EXPECT_EQ("", config.sync_group);
692}
693
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694// Tests that the list of supported codecs is created properly and ordered
deadbeef67cf2c12016-04-13 10:07:16 -0700695// correctly (such that opus appears first).
ossudedfd282016-06-14 07:12:39 -0700696// TODO(ossu): This test should move into a separate builtin audio codecs
697// module.
deadbeef67cf2c12016-04-13 10:07:16 -0700698TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) {
ossudedfd282016-06-14 07:12:39 -0700699 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000700 ASSERT_FALSE(codecs.empty());
701 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
702 EXPECT_EQ(48000, codecs[0].clockrate);
703 EXPECT_EQ(2, codecs[0].channels);
704 EXPECT_EQ(64000, codecs[0].bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705}
706
stefanba4c0e42016-02-04 04:12:24 -0800707TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
ossudedfd282016-06-14 07:12:39 -0700708 const std::vector<cricket::AudioCodec>& codecs = engine_->send_codecs();
stefanba4c0e42016-02-04 04:12:24 -0800709 bool opus_found = false;
710 for (cricket::AudioCodec codec : codecs) {
711 if (codec.name == "opus") {
712 EXPECT_TRUE(HasTransportCc(codec));
713 opus_found = true;
714 }
715 }
716 EXPECT_TRUE(opus_found);
717}
718
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719// Tests that we can find codecs by name or id, and that we interpret the
720// clockrate and bitrate fields properly.
721TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
722 cricket::AudioCodec codec;
723 webrtc::CodecInst codec_inst;
724 // Find PCMU with explicit clockrate and bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800725 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726 // Find ISAC with explicit clockrate and 0 bitrate.
solenberg26c8c912015-11-27 04:00:25 -0800727 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 // Find telephone-event with explicit clockrate and 0 bitrate.
solenberg2779bab2016-11-17 04:45:19 -0800729 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1,
730 &codec_inst));
731 // Find telephone-event with explicit clockrate and 0 bitrate.
732 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2,
solenberg26c8c912015-11-27 04:00:25 -0800733 &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734 // Find ISAC with a different payload id.
735 codec = kIsacCodec;
736 codec.id = 127;
solenberg26c8c912015-11-27 04:00:25 -0800737 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 EXPECT_EQ(codec.id, codec_inst.pltype);
739 // Find PCMU with a 0 clockrate.
740 codec = kPcmuCodec;
741 codec.clockrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800742 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 EXPECT_EQ(codec.id, codec_inst.pltype);
744 EXPECT_EQ(8000, codec_inst.plfreq);
745 // Find PCMU with a 0 bitrate.
746 codec = kPcmuCodec;
747 codec.bitrate = 0;
solenberg26c8c912015-11-27 04:00:25 -0800748 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000749 EXPECT_EQ(codec.id, codec_inst.pltype);
750 EXPECT_EQ(64000, codec_inst.rate);
751 // Find ISAC with an explicit bitrate.
752 codec = kIsacCodec;
753 codec.bitrate = 32000;
solenberg26c8c912015-11-27 04:00:25 -0800754 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 EXPECT_EQ(codec.id, codec_inst.pltype);
756 EXPECT_EQ(32000, codec_inst.rate);
757}
758
759// Test that we set our inbound codecs properly, including changing PT.
760TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
solenbergff976312016-03-30 23:28:51 -0700761 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200762 cricket::AudioRecvParameters parameters;
763 parameters.codecs.push_back(kIsacCodec);
764 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800765 parameters.codecs.push_back(kTelephoneEventCodec1);
766 parameters.codecs.push_back(kTelephoneEventCodec2);
767 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200768 parameters.codecs[2].id = 126;
769 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800770 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700771 int channel_num = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800772
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800774 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775 gcodec.plfreq = 16000;
776 gcodec.channels = 1;
777 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
778 EXPECT_EQ(106, gcodec.pltype);
779 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800780
tfarina5237aaf2015-11-10 23:44:30 -0800781 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782 gcodec.plfreq = 8000;
783 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
784 EXPECT_EQ(126, gcodec.pltype);
785 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800786
787 gcodec.plfreq = 32000;
788 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
789 EXPECT_EQ(107, gcodec.pltype);
790 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791}
792
793// Test that we fail to set an unknown inbound codec.
794TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -0700795 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200796 cricket::AudioRecvParameters parameters;
797 parameters.codecs.push_back(kIsacCodec);
deadbeef67cf2c12016-04-13 10:07:16 -0700798 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200799 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800}
801
802// Test that we fail if we have duplicate types in the inbound list.
803TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
solenbergff976312016-03-30 23:28:51 -0700804 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200805 cricket::AudioRecvParameters parameters;
806 parameters.codecs.push_back(kIsacCodec);
807 parameters.codecs.push_back(kCn16000Codec);
808 parameters.codecs[1].id = kIsacCodec.id;
809 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000810}
811
812// Test that we can decode OPUS without stereo parameters.
813TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
solenbergff976312016-03-30 23:28:51 -0700814 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200815 cricket::AudioRecvParameters parameters;
816 parameters.codecs.push_back(kIsacCodec);
817 parameters.codecs.push_back(kPcmuCodec);
818 parameters.codecs.push_back(kOpusCodec);
819 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800820 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -0700821 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800823 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824 // Even without stereo parameters, recv codecs still specify channels = 2.
825 EXPECT_EQ(2, opus.channels);
826 EXPECT_EQ(111, opus.pltype);
827 EXPECT_STREQ("opus", opus.plname);
828 opus.pltype = 0;
solenberg1ac56142015-10-13 03:58:19 -0700829 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 EXPECT_EQ(111, opus.pltype);
831}
832
833// Test that we can decode OPUS with stereo = 0.
834TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
solenbergff976312016-03-30 23:28:51 -0700835 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200836 cricket::AudioRecvParameters parameters;
837 parameters.codecs.push_back(kIsacCodec);
838 parameters.codecs.push_back(kPcmuCodec);
839 parameters.codecs.push_back(kOpusCodec);
840 parameters.codecs[2].params["stereo"] = "0";
841 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800842 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843 int channel_num2 = voe_.GetLastChannel();
844 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800845 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 // Even when stereo is off, recv codecs still specify channels = 2.
847 EXPECT_EQ(2, opus.channels);
848 EXPECT_EQ(111, opus.pltype);
849 EXPECT_STREQ("opus", opus.plname);
850 opus.pltype = 0;
851 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
852 EXPECT_EQ(111, opus.pltype);
853}
854
855// Test that we can decode OPUS with stereo = 1.
856TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
solenbergff976312016-03-30 23:28:51 -0700857 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200858 cricket::AudioRecvParameters parameters;
859 parameters.codecs.push_back(kIsacCodec);
860 parameters.codecs.push_back(kPcmuCodec);
861 parameters.codecs.push_back(kOpusCodec);
862 parameters.codecs[2].params["stereo"] = "1";
863 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800864 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865 int channel_num2 = voe_.GetLastChannel();
866 webrtc::CodecInst opus;
solenberg26c8c912015-11-27 04:00:25 -0800867 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868 EXPECT_EQ(2, opus.channels);
869 EXPECT_EQ(111, opus.pltype);
870 EXPECT_STREQ("opus", opus.plname);
871 opus.pltype = 0;
872 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
873 EXPECT_EQ(111, opus.pltype);
874}
875
876// Test that changes to recv codecs are applied to all streams.
877TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -0700878 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200879 cricket::AudioRecvParameters parameters;
880 parameters.codecs.push_back(kIsacCodec);
881 parameters.codecs.push_back(kPcmuCodec);
solenberg2779bab2016-11-17 04:45:19 -0800882 parameters.codecs.push_back(kTelephoneEventCodec1);
883 parameters.codecs.push_back(kTelephoneEventCodec2);
884 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200885 parameters.codecs[2].id = 126;
886 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800887 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 int channel_num2 = voe_.GetLastChannel();
solenberg2779bab2016-11-17 04:45:19 -0800889
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -0800891 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892 gcodec.plfreq = 16000;
893 gcodec.channels = 1;
894 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
895 EXPECT_EQ(106, gcodec.pltype);
896 EXPECT_STREQ("ISAC", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800897
tfarina5237aaf2015-11-10 23:44:30 -0800898 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899 gcodec.plfreq = 8000;
900 gcodec.channels = 1;
901 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
902 EXPECT_EQ(126, gcodec.pltype);
903 EXPECT_STREQ("telephone-event", gcodec.plname);
solenberg2779bab2016-11-17 04:45:19 -0800904
905 gcodec.plfreq = 32000;
906 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
907 EXPECT_EQ(107, gcodec.pltype);
908 EXPECT_STREQ("telephone-event", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909}
910
911TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
solenbergff976312016-03-30 23:28:51 -0700912 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200913 cricket::AudioRecvParameters parameters;
914 parameters.codecs.push_back(kIsacCodec);
solenberg2779bab2016-11-17 04:45:19 -0800915 parameters.codecs[0].id = 106; // collide with existing CN 32k
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200916 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917
solenberg2100c0b2017-03-01 11:29:29 -0800918 const auto& dm = GetRecvStreamConfig(kSsrcX).decoder_map;
kwibergd32bf752017-01-19 07:03:59 -0800919 ASSERT_EQ(1, dm.count(106));
920 EXPECT_EQ(webrtc::SdpAudioFormat("isac", 16000, 1), dm.at(106));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921}
922
923// Test that we can apply the same set of codecs again while playing.
924TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700925 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200926 cricket::AudioRecvParameters parameters;
927 parameters.codecs.push_back(kIsacCodec);
928 parameters.codecs.push_back(kCn16000Codec);
929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700930 channel_->SetPlayout(true);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200931 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932
933 // Changing the payload type of a codec should fail.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200934 parameters.codecs[0].id = 127;
935 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800936 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937}
938
939// Test that we can add a codec while playing.
940TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
solenbergff976312016-03-30 23:28:51 -0700941 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200942 cricket::AudioRecvParameters parameters;
943 parameters.codecs.push_back(kIsacCodec);
944 parameters.codecs.push_back(kCn16000Codec);
945 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
aleloi84ef6152016-08-04 05:28:21 -0700946 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200948 parameters.codecs.push_back(kOpusCodec);
949 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -0800950 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951 webrtc::CodecInst gcodec;
solenberg26c8c912015-11-27 04:00:25 -0800952 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000953 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
954}
955
956TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
solenbergff976312016-03-30 23:28:51 -0700957 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000959 // Test that when autobw is enabled, bitrate is kept as the default
960 // value. autobw is enabled for the following tests because the target
961 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962
963 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700964 TestMaxSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
966 // PCMU, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700967 TestMaxSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700970 TestMaxSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971}
972
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000973TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700974 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000976 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000977
978 // ISAC, default bitrate == 32000.
deadbeef80346142016-04-27 14:17:10 -0700979 TestMaxSendBandwidth(kIsacCodec, 40000, true, 40000);
980 TestMaxSendBandwidth(kIsacCodec, 16000, true, 16000);
981 // Rates above the max (56000) should be capped.
982 TestMaxSendBandwidth(kIsacCodec, 100000, true, 56000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984 // opus, default bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700985 TestMaxSendBandwidth(kOpusCodec, 96000, true, 96000);
986 TestMaxSendBandwidth(kOpusCodec, 48000, true, 48000);
987 // Rates above the max (510000) should be capped.
988 TestMaxSendBandwidth(kOpusCodec, 600000, true, 510000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989}
990
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000991TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
solenbergff976312016-03-30 23:28:51 -0700992 EXPECT_TRUE(SetupSendStream());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000993
994 // Test that we can only set a maximum bitrate for a fixed-rate codec
995 // if it's bigger than the fixed rate.
996
997 // PCMU, fixed bitrate == 64000.
deadbeef80346142016-04-27 14:17:10 -0700998 TestMaxSendBandwidth(kPcmuCodec, 0, true, 64000);
999 TestMaxSendBandwidth(kPcmuCodec, 1, false, 64000);
1000 TestMaxSendBandwidth(kPcmuCodec, 128000, true, 64000);
1001 TestMaxSendBandwidth(kPcmuCodec, 32000, false, 64000);
1002 TestMaxSendBandwidth(kPcmuCodec, 64000, true, 64000);
1003 TestMaxSendBandwidth(kPcmuCodec, 63999, false, 64000);
1004 TestMaxSendBandwidth(kPcmuCodec, 64001, true, 64000);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001005}
1006
1007TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001008 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009 const int kDesiredBitrate = 128000;
1010 cricket::AudioSendParameters parameters;
ossudedfd282016-06-14 07:12:39 -07001011 parameters.codecs = engine_->send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001012 parameters.max_bandwidth_bps = kDesiredBitrate;
solenberg059fb442016-10-26 05:12:24 -07001013 SetSendParameters(parameters);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001014
1015 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001016 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001017
solenberg2100c0b2017-03-01 11:29:29 -08001018 EXPECT_EQ(kDesiredBitrate, GetCodecBitrate(kSsrcX));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00001019}
1020
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021// Test that bitrate cannot be set for CBR codecs.
1022// Bitrate is ignored if it is higher than the fixed bitrate.
1023// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001024TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
solenbergff976312016-03-30 23:28:51 -07001025 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001026
1027 // PCMU, default bitrate == 64000.
solenberg059fb442016-10-26 05:12:24 -07001028 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001029 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001030
1031 send_parameters_.max_bandwidth_bps = 128000;
solenberg059fb442016-10-26 05:12:24 -07001032 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08001033 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001034
1035 send_parameters_.max_bandwidth_bps = 128;
1036 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
solenberg2100c0b2017-03-01 11:29:29 -08001037 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038}
1039
skvlade0d46372016-04-07 22:59:22 -07001040// Test that the per-stream bitrate limit and the global
1041// bitrate limit both apply.
1042TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) {
1043 EXPECT_TRUE(SetupSendStream());
1044
1045 // opus, default bitrate == 64000.
1046 SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000);
1047 SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000);
1048 SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000);
1049 SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000);
1050
1051 // CBR codecs allow both maximums to exceed the bitrate.
1052 SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000);
1053 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000);
1054 SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000);
1055 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000);
1056
1057 // CBR codecs don't allow per stream maximums to be too low.
1058 SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000);
1059 SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000);
1060}
1061
1062// Test that an attempt to set RtpParameters for a stream that does not exist
1063// fails.
1064TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) {
1065 EXPECT_TRUE(SetupChannel());
1066 webrtc::RtpParameters nonexistent_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001067 channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001068 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
1069
1070 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001071 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, nonexistent_parameters));
skvlade0d46372016-04-07 22:59:22 -07001072}
1073
1074TEST_F(WebRtcVoiceEngineTestFake,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001075 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvlade0d46372016-04-07 22:59:22 -07001076 // This test verifies that setting RtpParameters succeeds only if
1077 // the structure contains exactly one encoding.
1078 // TODO(skvlad): Update this test when we start supporting setting parameters
1079 // for each encoding individually.
1080
1081 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001082 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
skvlade0d46372016-04-07 22:59:22 -07001083 // Two or more encodings should result in failure.
1084 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
solenberg2100c0b2017-03-01 11:29:29 -08001085 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001086 // Zero encodings should also fail.
1087 parameters.encodings.clear();
solenberg2100c0b2017-03-01 11:29:29 -08001088 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08001089}
1090
1091// Changing the SSRC through RtpParameters is not allowed.
1092TEST_F(WebRtcVoiceEngineTestFake, CannotSetSsrcInRtpSendParameters) {
1093 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001094 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeeffb2aced2017-01-06 23:05:37 -08001095 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
solenberg2100c0b2017-03-01 11:29:29 -08001096 EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrcX, parameters));
skvlade0d46372016-04-07 22:59:22 -07001097}
1098
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001099// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001100// inactive through SetRtpSendParameters.
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001101TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) {
1102 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07001103 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08001104 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001105 // Get current parameters and change "active" to false.
solenberg2100c0b2017-03-01 11:29:29 -08001106 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001107 ASSERT_EQ(1u, parameters.encodings.size());
1108 ASSERT_TRUE(parameters.encodings[0].active);
1109 parameters.encodings[0].active = false;
solenberg2100c0b2017-03-01 11:29:29 -08001110 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1111 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001112
1113 // Now change it back to active and verify we resume sending.
1114 parameters.encodings[0].active = true;
solenberg2100c0b2017-03-01 11:29:29 -08001115 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, parameters));
1116 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter55dd7082016-05-03 13:50:11 -07001117}
1118
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001119// Test that SetRtpSendParameters configures the correct encoding channel for
1120// each SSRC.
skvlade0d46372016-04-07 22:59:22 -07001121TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) {
1122 SetupForMultiSendStream();
1123 // Create send streams.
1124 for (uint32_t ssrc : kSsrcs4) {
1125 EXPECT_TRUE(
1126 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc)));
1127 }
1128 // Configure one stream to be limited by the stream config, another to be
1129 // limited by the global max, and the third one with no per-stream limit
1130 // (still subject to the global limit).
solenberg059fb442016-10-26 05:12:24 -07001131 SetGlobalMaxBitrate(kOpusCodec, 64000);
skvlade0d46372016-04-07 22:59:22 -07001132 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000));
1133 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000));
1134 EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1));
1135
1136 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1137 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1]));
1138 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1139
1140 // Remove the global cap; the streams should switch to their respective
1141 // maximums (or remain unchanged if there was no other limit on them.)
solenberg059fb442016-10-26 05:12:24 -07001142 SetGlobalMaxBitrate(kOpusCodec, -1);
skvlade0d46372016-04-07 22:59:22 -07001143 EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0]));
1144 EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1]));
1145 EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2]));
1146}
1147
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001148// Test that GetRtpSendParameters returns the currently configured codecs.
1149TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001150 EXPECT_TRUE(SetupSendStream());
1151 cricket::AudioSendParameters parameters;
1152 parameters.codecs.push_back(kIsacCodec);
1153 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001154 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001155
solenberg2100c0b2017-03-01 11:29:29 -08001156 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001157 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001158 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1159 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001160}
1161
deadbeefcb443432016-12-12 11:12:36 -08001162// Test that GetRtpSendParameters returns an SSRC.
1163TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) {
1164 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001165 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001166 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001167 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001168}
1169
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001170// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001171TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001172 EXPECT_TRUE(SetupSendStream());
1173 cricket::AudioSendParameters parameters;
1174 parameters.codecs.push_back(kIsacCodec);
1175 parameters.codecs.push_back(kPcmuCodec);
solenberg059fb442016-10-26 05:12:24 -07001176 SetSendParameters(parameters);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001177
solenberg2100c0b2017-03-01 11:29:29 -08001178 webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrcX);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001179
1180 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001181 EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrcX, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001182
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001183 // ... And this shouldn't change the params returned by GetRtpSendParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001184 webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrcX);
1185 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrcX));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001186}
1187
1188// Test that GetRtpReceiveParameters returns the currently configured codecs.
1189TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) {
1190 EXPECT_TRUE(SetupRecvStream());
1191 cricket::AudioRecvParameters parameters;
1192 parameters.codecs.push_back(kIsacCodec);
1193 parameters.codecs.push_back(kPcmuCodec);
1194 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1195
1196 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001197 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001198 ASSERT_EQ(2u, rtp_parameters.codecs.size());
1199 EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]);
1200 EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]);
1201}
1202
deadbeefcb443432016-12-12 11:12:36 -08001203// Test that GetRtpReceiveParameters returns an SSRC.
1204TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersSsrc) {
1205 EXPECT_TRUE(SetupRecvStream());
1206 webrtc::RtpParameters rtp_parameters =
solenberg2100c0b2017-03-01 11:29:29 -08001207 channel_->GetRtpReceiveParameters(kSsrcX);
deadbeefcb443432016-12-12 11:12:36 -08001208 ASSERT_EQ(1u, rtp_parameters.encodings.size());
solenberg2100c0b2017-03-01 11:29:29 -08001209 EXPECT_EQ(kSsrcX, rtp_parameters.encodings[0].ssrc);
deadbeefcb443432016-12-12 11:12:36 -08001210}
1211
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001212// Test that if we set/get parameters multiple times, we get the same results.
1213TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) {
1214 EXPECT_TRUE(SetupRecvStream());
1215 cricket::AudioRecvParameters parameters;
1216 parameters.codecs.push_back(kIsacCodec);
1217 parameters.codecs.push_back(kPcmuCodec);
1218 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1219
1220 webrtc::RtpParameters initial_params =
solenberg2100c0b2017-03-01 11:29:29 -08001221 channel_->GetRtpReceiveParameters(kSsrcX);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001222
1223 // We should be able to set the params we just got.
solenberg2100c0b2017-03-01 11:29:29 -08001224 EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrcX, initial_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001225
1226 // ... And this shouldn't change the params returned by
1227 // GetRtpReceiveParameters.
solenberg2100c0b2017-03-01 11:29:29 -08001228 webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrcX);
1229 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrcX));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07001230}
1231
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001232// Test that we apply codecs properly.
1233TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
solenbergff976312016-03-30 23:28:51 -07001234 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001235 cricket::AudioSendParameters parameters;
1236 parameters.codecs.push_back(kIsacCodec);
1237 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001238 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001239 parameters.codecs[0].id = 96;
1240 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001241 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001242 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001243 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08001244 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07001245 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
1246 EXPECT_EQ(48000, send_codec_spec.codec_inst.rate);
1247 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
1248 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
ossu0c4b8492017-03-02 11:03:25 -08001249 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01001250 EXPECT_FALSE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001251}
1252
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001253// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
1254// to apply.
1255TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
solenbergff976312016-03-30 23:28:51 -07001256 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001257 cricket::AudioSendParameters parameters;
1258 parameters.codecs.push_back(kIsacCodec);
1259 parameters.codecs.push_back(kPcmuCodec);
kwiberg68061362016-06-14 08:04:47 -07001260 parameters.codecs.push_back(kCn8000Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001261 parameters.codecs[0].id = 96;
1262 parameters.codecs[0].bitrate = 48000;
minyue7a973442016-10-20 03:27:12 -07001263 const int initial_num = call_.GetNumCreatedSendStreams();
solenberg059fb442016-10-26 05:12:24 -07001264 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001265 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001266 // Calling SetSendCodec again with same codec which is already set.
1267 // In this case media channel shouldn't send codec to VoE.
solenberg059fb442016-10-26 05:12:24 -07001268 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001269 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001270}
1271
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001272// Verify that G722 is set with 16000 samples per second to WebRTC.
1273TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
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(kG722CodecSdp);
solenberg059fb442016-10-26 05:12:24 -07001277 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001278 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00001279 EXPECT_STREQ("G722", gcodec.plname);
1280 EXPECT_EQ(1, gcodec.channels);
1281 EXPECT_EQ(16000, gcodec.plfreq);
1282}
1283
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001284// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
solenbergff976312016-03-30 23:28:51 -07001286 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001287 cricket::AudioSendParameters parameters;
1288 parameters.codecs.push_back(kOpusCodec);
1289 parameters.codecs[0].bitrate = 0;
1290 parameters.codecs[0].clockrate = 50000;
1291 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001292}
1293
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001294// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001296 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001297 cricket::AudioSendParameters parameters;
1298 parameters.codecs.push_back(kOpusCodec);
1299 parameters.codecs[0].bitrate = 0;
1300 parameters.codecs[0].channels = 0;
1301 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001302}
1303
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001304// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001306 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001307 cricket::AudioSendParameters parameters;
1308 parameters.codecs.push_back(kOpusCodec);
1309 parameters.codecs[0].bitrate = 0;
1310 parameters.codecs[0].channels = 0;
1311 parameters.codecs[0].params["stereo"] = "1";
1312 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313}
1314
1315// Test that if channel is 1 for opus and there's no stereo, we fail.
1316TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001317 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001318 cricket::AudioSendParameters parameters;
1319 parameters.codecs.push_back(kOpusCodec);
1320 parameters.codecs[0].bitrate = 0;
1321 parameters.codecs[0].channels = 1;
1322 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323}
1324
1325// Test that if channel is 1 for opus and stereo=0, we fail.
1326TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001327 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 cricket::AudioSendParameters parameters;
1329 parameters.codecs.push_back(kOpusCodec);
1330 parameters.codecs[0].bitrate = 0;
1331 parameters.codecs[0].channels = 1;
1332 parameters.codecs[0].params["stereo"] = "0";
1333 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334}
1335
1336// Test that if channel is 1 for opus and stereo=1, we fail.
1337TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001338 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 cricket::AudioSendParameters parameters;
1340 parameters.codecs.push_back(kOpusCodec);
1341 parameters.codecs[0].bitrate = 0;
1342 parameters.codecs[0].channels = 1;
1343 parameters.codecs[0].params["stereo"] = "1";
1344 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345}
1346
1347// Test that with bitrate=0 and no stereo,
1348// channels and bitrate are 1 and 32000.
1349TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001350 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001351 cricket::AudioSendParameters parameters;
1352 parameters.codecs.push_back(kOpusCodec);
1353 parameters.codecs[0].bitrate = 0;
solenberg059fb442016-10-26 05:12:24 -07001354 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001355 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356}
1357
1358// Test that with bitrate=0 and stereo=0,
1359// channels and bitrate are 1 and 32000.
1360TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001361 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 cricket::AudioSendParameters parameters;
1363 parameters.codecs.push_back(kOpusCodec);
1364 parameters.codecs[0].bitrate = 0;
1365 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001366 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001367 CheckSendCodec(kSsrcX, "opus", 1, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368}
1369
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001370// Test that with bitrate=invalid and stereo=0,
1371// channels and bitrate are 1 and 32000.
1372TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001373 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001374 cricket::AudioSendParameters parameters;
1375 parameters.codecs.push_back(kOpusCodec);
1376 parameters.codecs[0].params["stereo"] = "0";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001377 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001379 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001380 CheckSendCodec(kSsrcX, "opus", 1, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001381
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001382 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001383 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001384 CheckSendCodec(kSsrcX, "opus", 1, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001385}
1386
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387// Test that with bitrate=0 and stereo=1,
1388// channels and bitrate are 2 and 64000.
1389TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001390 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001391 cricket::AudioSendParameters parameters;
1392 parameters.codecs.push_back(kOpusCodec);
1393 parameters.codecs[0].bitrate = 0;
1394 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001395 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001396 CheckSendCodec(kSsrcX, "opus", 2, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397}
1398
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001399// Test that with bitrate=invalid and stereo=1,
1400// channels and bitrate are 2 and 64000.
1401TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001402 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001403 cricket::AudioSendParameters parameters;
1404 parameters.codecs.push_back(kOpusCodec);
1405 parameters.codecs[0].params["stereo"] = "1";
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001406 // bitrate that's out of the range between 6000 and 510000 will be clamped.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 parameters.codecs[0].bitrate = 5999;
solenberg059fb442016-10-26 05:12:24 -07001408 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001409 CheckSendCodec(kSsrcX, "opus", 2, 6000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001410
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 parameters.codecs[0].bitrate = 510001;
solenberg059fb442016-10-26 05:12:24 -07001412 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001413 CheckSendCodec(kSsrcX, "opus", 2, 510000);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001414}
1415
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001416// Test that with bitrate=N and stereo unset,
1417// channels and bitrate are 1 and N.
1418TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
solenbergff976312016-03-30 23:28:51 -07001419 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 cricket::AudioSendParameters parameters;
1421 parameters.codecs.push_back(kOpusCodec);
1422 parameters.codecs[0].bitrate = 96000;
solenberg059fb442016-10-26 05:12:24 -07001423 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001424 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425 EXPECT_EQ(111, gcodec.pltype);
1426 EXPECT_EQ(96000, gcodec.rate);
1427 EXPECT_STREQ("opus", gcodec.plname);
1428 EXPECT_EQ(1, gcodec.channels);
1429 EXPECT_EQ(48000, gcodec.plfreq);
1430}
1431
1432// Test that with bitrate=N and stereo=0,
1433// channels and bitrate are 1 and N.
1434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
solenbergff976312016-03-30 23:28:51 -07001435 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001436 cricket::AudioSendParameters parameters;
1437 parameters.codecs.push_back(kOpusCodec);
1438 parameters.codecs[0].bitrate = 30000;
1439 parameters.codecs[0].params["stereo"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001440 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001441 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001442}
1443
1444// Test that with bitrate=N and without any parameters,
1445// channels and bitrate are 1 and N.
1446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
solenbergff976312016-03-30 23:28:51 -07001447 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001448 cricket::AudioSendParameters parameters;
1449 parameters.codecs.push_back(kOpusCodec);
1450 parameters.codecs[0].bitrate = 30000;
solenberg059fb442016-10-26 05:12:24 -07001451 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001452 CheckSendCodec(kSsrcX, "opus", 1, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453}
1454
1455// Test that with bitrate=N and stereo=1,
1456// channels and bitrate are 2 and N.
1457TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
solenbergff976312016-03-30 23:28:51 -07001458 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 cricket::AudioSendParameters parameters;
1460 parameters.codecs.push_back(kOpusCodec);
1461 parameters.codecs[0].bitrate = 30000;
1462 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001463 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001464 CheckSendCodec(kSsrcX, "opus", 2, 30000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465}
1466
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001467// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1468// Also test that the "maxaveragebitrate" can't be set to values outside the
1469// range of 6000 and 510000
1470TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
solenbergff976312016-03-30 23:28:51 -07001471 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].bitrate = 30000;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001475 // Ignore if less than 6000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001476 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
solenberg059fb442016-10-26 05:12:24 -07001477 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001478 EXPECT_EQ(6000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001479
1480 // Ignore if larger than 510000.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001481 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
solenberg059fb442016-10-26 05:12:24 -07001482 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001483 EXPECT_EQ(510000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001484
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001485 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
solenberg059fb442016-10-26 05:12:24 -07001486 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001487 EXPECT_EQ(200000, GetCodecBitrate(kSsrcX));
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001488}
1489
stefan13f1a0a2016-11-30 07:22:58 -08001490TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithBitrates) {
1491 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1492 200000);
1493}
1494
1495TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithHighMaxBitrate) {
1496 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
1497}
1498
1499TEST_F(WebRtcVoiceEngineTestFake,
1500 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
1501 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
1502}
1503
1504TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCapsMinAndStartBitrate) {
1505 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
1506}
1507
1508TEST_F(WebRtcVoiceEngineTestFake,
1509 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
1510 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1511 200000);
1512 send_parameters_.max_bandwidth_bps = 300000;
1513 SetSendParameters(send_parameters_);
1514 EXPECT_EQ(100000, call_.GetConfig().bitrate_config.min_bitrate_bps)
1515 << "Setting max bitrate should keep previous min bitrate.";
1516 EXPECT_EQ(-1, call_.GetConfig().bitrate_config.start_bitrate_bps)
1517 << "Setting max bitrate should not reset start bitrate.";
1518 EXPECT_EQ(300000, call_.GetConfig().bitrate_config.max_bitrate_bps);
1519}
1520
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001521// Test that we can enable NACK with opus as caller.
1522TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
solenbergff976312016-03-30 23:28:51 -07001523 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001524 cricket::AudioSendParameters parameters;
1525 parameters.codecs.push_back(kOpusCodec);
1526 parameters.codecs[0].AddFeedbackParam(
1527 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1528 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001529 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001530 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001531 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532}
1533
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001534// Test that we can enable NACK with opus as callee.
1535TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
solenbergff976312016-03-30 23:28:51 -07001536 EXPECT_TRUE(SetupRecvStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001537 cricket::AudioSendParameters parameters;
1538 parameters.codecs.push_back(kOpusCodec);
1539 parameters.codecs[0].AddFeedbackParam(
1540 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1541 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001542 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001543 SetSendParameters(parameters);
deadbeefb56069e2016-05-06 04:57:03 -07001544 // NACK should be enabled even with no send stream.
solenberg2100c0b2017-03-01 11:29:29 -08001545 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001546
1547 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08001548 cricket::StreamParams::CreateLegacy(kSsrcX)));
1549 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001550}
1551
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552// Test that we can enable NACK on receive streams.
1553TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001554 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001555 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 cricket::AudioSendParameters parameters;
1557 parameters.codecs.push_back(kOpusCodec);
1558 parameters.codecs[0].AddFeedbackParam(
1559 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1560 cricket::kParamValueEmpty));
solenberg2100c0b2017-03-01 11:29:29 -08001561 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1562 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
solenberg059fb442016-10-26 05:12:24 -07001563 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001564 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1565 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566}
1567
1568// Test that we can disable NACK.
1569TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
solenbergff976312016-03-30 23:28:51 -07001570 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 cricket::AudioSendParameters parameters;
1572 parameters.codecs.push_back(kOpusCodec);
1573 parameters.codecs[0].AddFeedbackParam(
1574 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1575 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001576 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001577 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001578
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001579 parameters.codecs.clear();
1580 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001581 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001582 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583}
1584
1585// Test that we can disable NACK on receive streams.
1586TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
solenbergff976312016-03-30 23:28:51 -07001587 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08001588 EXPECT_TRUE(AddRecvStream(kSsrcY));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 cricket::AudioSendParameters parameters;
1590 parameters.codecs.push_back(kOpusCodec);
1591 parameters.codecs[0].AddFeedbackParam(
1592 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1593 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001594 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001595 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1596 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001598 parameters.codecs.clear();
1599 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001600 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001601 EXPECT_EQ(0, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
1602 EXPECT_EQ(0, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603}
1604
1605// Test that NACK is enabled on a new receive stream.
1606TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
solenbergff976312016-03-30 23:28:51 -07001607 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001608 cricket::AudioSendParameters parameters;
1609 parameters.codecs.push_back(kIsacCodec);
1610 parameters.codecs.push_back(kCn16000Codec);
1611 parameters.codecs[0].AddFeedbackParam(
1612 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1613 cricket::kParamValueEmpty));
solenberg059fb442016-10-26 05:12:24 -07001614 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001615 EXPECT_EQ(kRtpHistoryMs, GetSendStreamConfig(kSsrcX).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001616
solenberg2100c0b2017-03-01 11:29:29 -08001617 EXPECT_TRUE(AddRecvStream(kSsrcY));
1618 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcY).rtp.nack.rtp_history_ms);
1619 EXPECT_TRUE(AddRecvStream(kSsrcZ));
1620 EXPECT_EQ(kRtpHistoryMs, GetRecvStreamConfig(kSsrcZ).rtp.nack.rtp_history_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621}
1622
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001623// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001624TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
solenbergff976312016-03-30 23:28:51 -07001625 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001626 cricket::AudioSendParameters parameters;
1627 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001628 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001629 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001630}
1631
1632// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001633TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
solenbergff976312016-03-30 23:28:51 -07001634 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kOpusCodec);
1637 parameters.codecs[0].bitrate = 0;
1638 parameters.codecs[0].params["useinbandfec"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001639 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001640 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001641}
1642
1643// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001644TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
solenbergff976312016-03-30 23:28:51 -07001645 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001646 cricket::AudioSendParameters parameters;
1647 parameters.codecs.push_back(kOpusCodec);
1648 parameters.codecs[0].bitrate = 0;
1649 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001650 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001651 EXPECT_TRUE(GetCodecFec(kSsrcX));
1652 CheckSendCodec(kSsrcX, "opus", 1, 32000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001653}
1654
1655// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001656TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
solenbergff976312016-03-30 23:28:51 -07001657 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001658 cricket::AudioSendParameters parameters;
1659 parameters.codecs.push_back(kOpusCodec);
1660 parameters.codecs[0].bitrate = 0;
1661 parameters.codecs[0].params["stereo"] = "1";
1662 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001663 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001664 EXPECT_TRUE(GetCodecFec(kSsrcX));
1665 CheckSendCodec(kSsrcX, "opus", 2, 64000);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001666}
1667
1668// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001669TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
solenbergff976312016-03-30 23:28:51 -07001670 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kIsacCodec);
solenberg059fb442016-10-26 05:12:24 -07001673 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001674 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001675}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001676
1677// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1678TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
solenbergff976312016-03-30 23:28:51 -07001679 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001680 cricket::AudioSendParameters parameters;
1681 parameters.codecs.push_back(kIsacCodec);
1682 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001683 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001684 EXPECT_FALSE(GetCodecFec(kSsrcX));
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001685}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001686
1687// Test that Opus FEC status can be changed.
1688TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
solenbergff976312016-03-30 23:28:51 -07001689 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001690 cricket::AudioSendParameters parameters;
1691 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001692 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001693 EXPECT_FALSE(GetCodecFec(kSsrcX));
minyue7a973442016-10-20 03:27:12 -07001694
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001695 parameters.codecs[0].params["useinbandfec"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001696 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001697 EXPECT_TRUE(GetCodecFec(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001698}
1699
stefanba4c0e42016-02-04 04:12:24 -08001700TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
solenbergff976312016-03-30 23:28:51 -07001701 EXPECT_TRUE(SetupChannel());
stefanba4c0e42016-02-04 04:12:24 -08001702 cricket::AudioSendParameters send_parameters;
1703 send_parameters.codecs.push_back(kOpusCodec);
1704 EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
solenberg059fb442016-10-26 05:12:24 -07001705 SetSendParameters(send_parameters);
stefanba4c0e42016-02-04 04:12:24 -08001706
1707 cricket::AudioRecvParameters recv_parameters;
1708 recv_parameters.codecs.push_back(kIsacCodec);
1709 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters));
solenberg2100c0b2017-03-01 11:29:29 -08001710 EXPECT_TRUE(AddRecvStream(kSsrcX));
1711 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001712 EXPECT_FALSE(
solenberg2100c0b2017-03-01 11:29:29 -08001713 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001714
ossudedfd282016-06-14 07:12:39 -07001715 send_parameters.codecs = engine_->send_codecs();
solenberg059fb442016-10-26 05:12:24 -07001716 SetSendParameters(send_parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001717 ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrcX) != nullptr);
stefanba4c0e42016-02-04 04:12:24 -08001718 EXPECT_TRUE(
solenberg2100c0b2017-03-01 11:29:29 -08001719 call_.GetAudioReceiveStream(kSsrcX)->GetConfig().rtp.transport_cc);
stefanba4c0e42016-02-04 04:12:24 -08001720}
1721
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001722// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1723TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
solenbergff976312016-03-30 23:28:51 -07001724 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001725 cricket::AudioSendParameters parameters;
1726 parameters.codecs.push_back(kOpusCodec);
1727 parameters.codecs[0].bitrate = 0;
1728 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001729 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001730 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
1731 EXPECT_EQ(12000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001732
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001733 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001734 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001735 EXPECT_EQ(24000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001736}
1737
1738// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1739TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
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(kOpusCodec);
1743 parameters.codecs[0].bitrate = 0;
1744 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
solenberg059fb442016-10-26 05:12:24 -07001745 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001746 EXPECT_EQ(8001, GetOpusMaxPlaybackRate(kSsrcX));
1747 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001748
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001749 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001750 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001751 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001752}
1753
1754// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1755TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
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(kOpusCodec);
1759 parameters.codecs[0].bitrate = 0;
1760 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
solenberg059fb442016-10-26 05:12:24 -07001761 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001762 EXPECT_EQ(12001, GetOpusMaxPlaybackRate(kSsrcX));
1763 EXPECT_EQ(20000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001764
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001765 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001766 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001767 EXPECT_EQ(40000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001768}
1769
1770// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1771TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
solenbergff976312016-03-30 23:28:51 -07001772 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001773 cricket::AudioSendParameters parameters;
1774 parameters.codecs.push_back(kOpusCodec);
1775 parameters.codecs[0].bitrate = 0;
1776 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
solenberg059fb442016-10-26 05:12:24 -07001777 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001778 EXPECT_EQ(16001, GetOpusMaxPlaybackRate(kSsrcX));
1779 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001780
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001781 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001782 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001783 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001784}
1785
1786// Test 24000 < maxplaybackrate triggers Opus full band mode.
1787TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
solenbergff976312016-03-30 23:28:51 -07001788 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001789 cricket::AudioSendParameters parameters;
1790 parameters.codecs.push_back(kOpusCodec);
1791 parameters.codecs[0].bitrate = 0;
1792 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
solenberg059fb442016-10-26 05:12:24 -07001793 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001794 EXPECT_EQ(24001, GetOpusMaxPlaybackRate(kSsrcX));
1795 EXPECT_EQ(32000, GetCodecBitrate(kSsrcX));
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001796
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
solenberg059fb442016-10-26 05:12:24 -07001798 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001799 EXPECT_EQ(64000, GetCodecBitrate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001800}
1801
1802// Test Opus that without maxplaybackrate, default playback rate is used.
1803TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001804 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001805 cricket::AudioSendParameters parameters;
1806 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001807 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001808 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001809}
1810
1811// Test the with non-Opus, maxplaybackrate has no effect.
1812TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
solenbergff976312016-03-30 23:28:51 -07001813 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001814 cricket::AudioSendParameters parameters;
1815 parameters.codecs.push_back(kIsacCodec);
1816 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
solenberg059fb442016-10-26 05:12:24 -07001817 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001818 EXPECT_EQ(0, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001819}
1820
1821// Test maxplaybackrate can be set on two streams.
1822TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
solenbergff976312016-03-30 23:28:51 -07001823 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001824 cricket::AudioSendParameters parameters;
1825 parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001826 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001827 EXPECT_EQ(48000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001828
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001829 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
solenberg059fb442016-10-26 05:12:24 -07001830 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001831 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001832
solenberg2100c0b2017-03-01 11:29:29 -08001833 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcY));
1834 EXPECT_EQ(8000, GetOpusMaxPlaybackRate(kSsrcY));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001835}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001836
Minyue Li7100dcd2015-03-27 05:05:59 +01001837// Test that with usedtx=0, Opus DTX is off.
1838TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001839 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001840 cricket::AudioSendParameters parameters;
1841 parameters.codecs.push_back(kOpusCodec);
1842 parameters.codecs[0].params["usedtx"] = "0";
solenberg059fb442016-10-26 05:12:24 -07001843 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001844 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001845}
1846
1847// Test that with usedtx=1, Opus DTX is on.
1848TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
solenbergff976312016-03-30 23:28:51 -07001849 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001850 cricket::AudioSendParameters parameters;
1851 parameters.codecs.push_back(kOpusCodec);
1852 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001853 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001854 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001855}
1856
1857// Test that usedtx=1 works with stereo Opus.
1858TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
solenbergff976312016-03-30 23:28:51 -07001859 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001860 cricket::AudioSendParameters parameters;
1861 parameters.codecs.push_back(kOpusCodec);
1862 parameters.codecs[0].params["usedtx"] = "1";
1863 parameters.codecs[0].params["stereo"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001864 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001865 EXPECT_TRUE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001866}
1867
1868// Test that usedtx=1 does not work with non Opus.
1869TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
solenbergff976312016-03-30 23:28:51 -07001870 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001871 cricket::AudioSendParameters parameters;
1872 parameters.codecs.push_back(kIsacCodec);
1873 parameters.codecs[0].params["usedtx"] = "1";
solenberg059fb442016-10-26 05:12:24 -07001874 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001875 EXPECT_FALSE(GetOpusDtx(kSsrcX));
Minyue Li7100dcd2015-03-27 05:05:59 +01001876}
1877
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001878// Test that we can switch back and forth between Opus and ISAC with CN.
1879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
solenbergff976312016-03-30 23:28:51 -07001880 EXPECT_TRUE(SetupSendStream());
minyue7a973442016-10-20 03:27:12 -07001881
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001882 cricket::AudioSendParameters opus_parameters;
1883 opus_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001884 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001885 {
solenberg2100c0b2017-03-01 11:29:29 -08001886 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001887 EXPECT_EQ(111, gcodec.pltype);
1888 EXPECT_STREQ("opus", gcodec.plname);
1889 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001891 cricket::AudioSendParameters isac_parameters;
1892 isac_parameters.codecs.push_back(kIsacCodec);
1893 isac_parameters.codecs.push_back(kCn16000Codec);
1894 isac_parameters.codecs.push_back(kOpusCodec);
solenberg059fb442016-10-26 05:12:24 -07001895 SetSendParameters(isac_parameters);
minyue7a973442016-10-20 03:27:12 -07001896 {
solenberg2100c0b2017-03-01 11:29:29 -08001897 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001898 EXPECT_EQ(103, gcodec.pltype);
1899 EXPECT_STREQ("ISAC", gcodec.plname);
1900 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901
solenberg059fb442016-10-26 05:12:24 -07001902 SetSendParameters(opus_parameters);
minyue7a973442016-10-20 03:27:12 -07001903 {
solenberg2100c0b2017-03-01 11:29:29 -08001904 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001905 EXPECT_EQ(111, gcodec.pltype);
1906 EXPECT_STREQ("opus", gcodec.plname);
1907 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001908}
1909
1910// Test that we handle various ways of specifying bitrate.
1911TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
solenbergff976312016-03-30 23:28:51 -07001912 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001913 cricket::AudioSendParameters parameters;
1914 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
solenberg059fb442016-10-26 05:12:24 -07001915 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001916 {
solenberg2100c0b2017-03-01 11:29:29 -08001917 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001918 EXPECT_EQ(103, gcodec.pltype);
1919 EXPECT_STREQ("ISAC", gcodec.plname);
1920 EXPECT_EQ(32000, gcodec.rate);
1921 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001922
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001923 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001924 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001925 {
solenberg2100c0b2017-03-01 11:29:29 -08001926 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001927 EXPECT_EQ(103, gcodec.pltype);
1928 EXPECT_STREQ("ISAC", gcodec.plname);
ossue1405ad2017-01-23 08:55:48 -08001929 EXPECT_EQ(32000, gcodec.rate);
minyue7a973442016-10-20 03:27:12 -07001930 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001931 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
solenberg059fb442016-10-26 05:12:24 -07001932 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001933 {
solenberg2100c0b2017-03-01 11:29:29 -08001934 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001935 EXPECT_EQ(103, gcodec.pltype);
1936 EXPECT_STREQ("ISAC", gcodec.plname);
1937 EXPECT_EQ(28000, gcodec.rate);
1938 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001939
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
solenberg059fb442016-10-26 05:12:24 -07001941 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001942 {
solenberg2100c0b2017-03-01 11:29:29 -08001943 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001944 EXPECT_EQ(0, gcodec.pltype);
1945 EXPECT_STREQ("PCMU", gcodec.plname);
1946 EXPECT_EQ(64000, gcodec.rate);
1947 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001949 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001950 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001951 {
solenberg2100c0b2017-03-01 11:29:29 -08001952 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001953 EXPECT_EQ(0, gcodec.pltype);
1954 EXPECT_STREQ("PCMU", gcodec.plname);
1955 EXPECT_EQ(64000, gcodec.rate);
1956 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001958 parameters.codecs[0] = kOpusCodec;
1959 parameters.codecs[0].bitrate = 0; // bitrate == default
solenberg059fb442016-10-26 05:12:24 -07001960 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001961 {
solenberg2100c0b2017-03-01 11:29:29 -08001962 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
minyue7a973442016-10-20 03:27:12 -07001963 EXPECT_EQ(111, gcodec.pltype);
1964 EXPECT_STREQ("opus", gcodec.plname);
1965 EXPECT_EQ(32000, gcodec.rate);
1966 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967}
1968
Brave Yao5225dd82015-03-26 07:39:19 +08001969// Test that we could set packet size specified in kCodecParamPTime.
1970TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
solenbergff976312016-03-30 23:28:51 -07001971 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001972 cricket::AudioSendParameters parameters;
1973 parameters.codecs.push_back(kOpusCodec);
1974 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001975 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001976 EXPECT_EQ(1920, GetCodecPacSize(kSsrcX)); // Opus gets 40ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001977
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001978 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
solenberg059fb442016-10-26 05:12:24 -07001979 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001980 EXPECT_EQ(480, GetCodecPacSize(kSsrcX)); // Opus gets 10ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001981
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001982 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
solenberg059fb442016-10-26 05:12:24 -07001983 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08001984 EXPECT_EQ(2880, GetCodecPacSize(kSsrcX)); // Opus gets 60ms.
Brave Yao5225dd82015-03-26 07:39:19 +08001985
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001986 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1987 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
solenberg059fb442016-10-26 05:12:24 -07001988 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001989 EXPECT_EQ(480, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001990 kSsrcX)); // Isac gets 30ms as the next smallest value.
Brave Yao5225dd82015-03-26 07:39:19 +08001991
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001992 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1993 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
solenberg059fb442016-10-26 05:12:24 -07001994 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07001995 EXPECT_EQ(640, GetCodecPacSize(
solenberg2100c0b2017-03-01 11:29:29 -08001996 kSsrcX)); // G722 gets 40ms @16kHz as defined in VoE.
Brave Yao5225dd82015-03-26 07:39:19 +08001997}
1998
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001999// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002000TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
solenbergff976312016-03-30 23:28:51 -07002001 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002002 cricket::AudioSendParameters parameters;
2003 EXPECT_FALSE(channel_->SetSendParameters(parameters));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002004}
2005
2006// Test that we can set send codecs even with telephone-event codec as the first
2007// one on the list.
2008TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
solenbergff976312016-03-30 23:28:51 -07002009 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002010 cricket::AudioSendParameters parameters;
solenberg2779bab2016-11-17 04:45:19 -08002011 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002012 parameters.codecs.push_back(kIsacCodec);
2013 parameters.codecs.push_back(kPcmuCodec);
2014 parameters.codecs[0].id = 98; // DTMF
2015 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002016 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002017 const auto& gcodec = GetSendStreamConfig(kSsrcX).send_codec_spec.codec_inst;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002018 EXPECT_EQ(96, gcodec.pltype);
2019 EXPECT_STREQ("ISAC", gcodec.plname);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002020 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002021}
2022
solenberg31642aa2016-03-14 08:00:37 -07002023// Test that payload type range is limited for telephone-event codec.
2024TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) {
solenbergff976312016-03-30 23:28:51 -07002025 EXPECT_TRUE(SetupSendStream());
solenberg31642aa2016-03-14 08:00:37 -07002026 cricket::AudioSendParameters parameters;
solenbergffbbcac2016-11-17 05:25:37 -08002027 parameters.codecs.push_back(kTelephoneEventCodec2);
solenberg31642aa2016-03-14 08:00:37 -07002028 parameters.codecs.push_back(kIsacCodec);
2029 parameters.codecs[0].id = 0; // DTMF
2030 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002031 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002032 EXPECT_TRUE(channel_->CanInsertDtmf());
2033 parameters.codecs[0].id = 128; // DTMF
2034 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2035 EXPECT_FALSE(channel_->CanInsertDtmf());
2036 parameters.codecs[0].id = 127;
solenberg059fb442016-10-26 05:12:24 -07002037 SetSendParameters(parameters);
solenberg31642aa2016-03-14 08:00:37 -07002038 EXPECT_TRUE(channel_->CanInsertDtmf());
2039 parameters.codecs[0].id = -1; // DTMF
2040 EXPECT_FALSE(channel_->SetSendParameters(parameters));
2041 EXPECT_FALSE(channel_->CanInsertDtmf());
2042}
2043
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00002044// Test that we can set send codecs even with CN codec as the first
2045// one on the list.
2046TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
solenbergff976312016-03-30 23:28:51 -07002047 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002048 cricket::AudioSendParameters parameters;
2049 parameters.codecs.push_back(kCn16000Codec);
2050 parameters.codecs.push_back(kIsacCodec);
2051 parameters.codecs.push_back(kPcmuCodec);
2052 parameters.codecs[0].id = 98; // wideband CN
2053 parameters.codecs[1].id = 96;
solenberg059fb442016-10-26 05:12:24 -07002054 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002055 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002056 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2057 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2058 EXPECT_EQ(98, send_codec_spec.cng_payload_type);
2059 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060}
2061
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002062// Test that we set VAD and DTMF types correctly as caller.
2063TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
solenbergff976312016-03-30 23:28:51 -07002064 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002065 cricket::AudioSendParameters parameters;
2066 parameters.codecs.push_back(kIsacCodec);
2067 parameters.codecs.push_back(kPcmuCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002068 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002069 parameters.codecs.push_back(kCn16000Codec);
2070 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002071 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002072 parameters.codecs[0].id = 96;
2073 parameters.codecs[2].id = 97; // wideband CN
2074 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002075 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002076 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002077 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2078 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2079 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2080 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2081 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2082 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002083 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002084}
2085
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002086// Test that we set VAD and DTMF types correctly as callee.
2087TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
solenbergff976312016-03-30 23:28:51 -07002088 EXPECT_TRUE(SetupChannel());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002089 cricket::AudioSendParameters parameters;
2090 parameters.codecs.push_back(kIsacCodec);
2091 parameters.codecs.push_back(kPcmuCodec);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002092 // TODO(juberti): cn 32000
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002093 parameters.codecs.push_back(kCn16000Codec);
2094 parameters.codecs.push_back(kCn8000Codec);
solenbergffbbcac2016-11-17 05:25:37 -08002095 parameters.codecs.push_back(kTelephoneEventCodec2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002096 parameters.codecs[0].id = 96;
2097 parameters.codecs[2].id = 97; // wideband CN
2098 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002099 SetSendParameters(parameters);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002100 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002101 cricket::StreamParams::CreateLegacy(kSsrcX)));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002102
solenberg2100c0b2017-03-01 11:29:29 -08002103 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002104 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2105 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2106 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2107 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2108 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2109 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002110 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002111}
2112
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002113// Test that we only apply VAD if we have a CN codec that matches the
2114// send codec clockrate.
2115TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
solenbergff976312016-03-30 23:28:51 -07002116 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002117 cricket::AudioSendParameters parameters;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002119 parameters.codecs.push_back(kIsacCodec);
2120 parameters.codecs.push_back(kCn16000Codec);
2121 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002122 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002123 {
solenberg2100c0b2017-03-01 11:29:29 -08002124 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002125 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2126 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2127 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2128 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2129 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
2130 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002131 // Set PCMU(8K) and CN(16K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002132 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002133 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002134 {
solenberg2100c0b2017-03-01 11:29:29 -08002135 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002136 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2137 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2138 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002139 // Set PCMU(8K) and CN(8K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002140 parameters.codecs[1] = kCn8000Codec;
solenberg059fb442016-10-26 05:12:24 -07002141 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002142 {
solenberg2100c0b2017-03-01 11:29:29 -08002143 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002144 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
2145 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2146 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2147 EXPECT_EQ(13, send_codec_spec.cng_payload_type);
2148 EXPECT_EQ(webrtc::kFreq8000Hz, send_codec_spec.cng_plfreq);
2149 }
Brave Yao5225dd82015-03-26 07:39:19 +08002150 // Set ISAC(16K) and CN(8K). VAD should not be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002151 parameters.codecs[0] = kIsacCodec;
solenberg059fb442016-10-26 05:12:24 -07002152 SetSendParameters(parameters);
minyue7a973442016-10-20 03:27:12 -07002153 {
solenberg2100c0b2017-03-01 11:29:29 -08002154 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002155 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2156 EXPECT_NE(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2157 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158}
2159
2160// Test that we perform case-insensitive matching of codec names.
2161TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
solenbergff976312016-03-30 23:28:51 -07002162 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002163 cricket::AudioSendParameters parameters;
2164 parameters.codecs.push_back(kIsacCodec);
2165 parameters.codecs.push_back(kPcmuCodec);
2166 parameters.codecs.push_back(kCn16000Codec);
2167 parameters.codecs.push_back(kCn8000Codec);
solenberg2779bab2016-11-17 04:45:19 -08002168 parameters.codecs.push_back(kTelephoneEventCodec1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 parameters.codecs[0].name = "iSaC";
2170 parameters.codecs[0].id = 96;
2171 parameters.codecs[2].id = 97; // wideband CN
2172 parameters.codecs[4].id = 98; // DTMF
solenberg059fb442016-10-26 05:12:24 -07002173 SetSendParameters(parameters);
solenberg2100c0b2017-03-01 11:29:29 -08002174 const auto& send_codec_spec = GetSendStreamConfig(kSsrcX).send_codec_spec;
minyue7a973442016-10-20 03:27:12 -07002175 EXPECT_EQ(96, send_codec_spec.codec_inst.pltype);
2176 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2177 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2178 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2179 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2180 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
Fredrik Solenbergb5727682015-12-04 15:22:19 +01002181 EXPECT_TRUE(channel_->CanInsertDtmf());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002182}
2183
stefanba4c0e42016-02-04 04:12:24 -08002184class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
2185 public:
2186 WebRtcVoiceEngineWithSendSideBweTest()
2187 : WebRtcVoiceEngineTestFake("WebRTC-Audio-SendSideBwe/Enabled/") {}
2188};
2189
2190TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
2191 SupportsTransportSequenceNumberHeaderExtension) {
solenbergbc37fc82016-04-04 09:54:44 -07002192 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
stefanba4c0e42016-02-04 04:12:24 -08002193 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -07002194 for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
2195 if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
2196 EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
stefanba4c0e42016-02-04 04:12:24 -08002197 extension.id);
2198 return;
2199 }
2200 }
2201 FAIL() << "Transport sequence number extension not in header-extension list.";
2202}
2203
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002204// Test support for audio level header extension.
2205TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002206 TestSetSendRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002207}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002208TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002209 TestSetRecvRtpHeaderExtensions(webrtc::RtpExtension::kAudioLevelUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002210}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00002211
solenbergd4adce42016-11-17 06:26:52 -08002212// Test support for transport sequence number header extension.
2213TEST_F(WebRtcVoiceEngineTestFake, SendTransportSequenceNumberHeaderExtensions) {
2214 TestSetSendRtpHeaderExtensions(
2215 webrtc::RtpExtension::kTransportSequenceNumberUri);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00002216}
solenbergd4adce42016-11-17 06:26:52 -08002217TEST_F(WebRtcVoiceEngineTestFake, RecvTransportSequenceNumberHeaderExtensions) {
2218 TestSetRecvRtpHeaderExtensions(
2219 webrtc::RtpExtension::kTransportSequenceNumberUri);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002220}
2221
solenberg1ac56142015-10-13 03:58:19 -07002222// Test that we can create a channel and start sending on it.
2223TEST_F(WebRtcVoiceEngineTestFake, Send) {
solenbergff976312016-03-30 23:28:51 -07002224 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002225 SetSendParameters(send_parameters_);
2226 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002227 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002228 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002229 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002230}
2231
2232// Test that a channel will send if and only if it has a source and is enabled
2233// for sending.
2234TEST_F(WebRtcVoiceEngineTestFake, SendStateWithAndWithoutSource) {
solenbergff976312016-03-30 23:28:51 -07002235 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002236 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002237 SetAudioSend(kSsrcX, true, nullptr);
solenberg059fb442016-10-26 05:12:24 -07002238 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002239 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
2240 SetAudioSend(kSsrcX, true, &fake_source_);
2241 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
2242 SetAudioSend(kSsrcX, true, nullptr);
2243 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg1ac56142015-10-13 03:58:19 -07002244}
2245
solenberg94218532016-06-16 10:53:22 -07002246// Test that a channel is muted/unmuted.
2247TEST_F(WebRtcVoiceEngineTestFake, SendStateMuteUnmute) {
2248 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002249 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002250 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2251 SetAudioSend(kSsrcX, true, nullptr);
2252 EXPECT_FALSE(GetSendStream(kSsrcX).muted());
2253 SetAudioSend(kSsrcX, false, nullptr);
2254 EXPECT_TRUE(GetSendStream(kSsrcX).muted());
solenberg94218532016-06-16 10:53:22 -07002255}
2256
solenberg6d6e7c52016-04-13 09:07:30 -07002257// Test that SetSendParameters() does not alter a stream's send state.
2258TEST_F(WebRtcVoiceEngineTestFake, SendStateWhenStreamsAreRecreated) {
2259 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002260 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002261
2262 // Turn on sending.
solenberg059fb442016-10-26 05:12:24 -07002263 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002264 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002265
2266 // Changing RTP header extensions will recreate the AudioSendStream.
2267 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002268 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
solenberg059fb442016-10-26 05:12:24 -07002269 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002270 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002271
2272 // Turn off sending.
solenberg059fb442016-10-26 05:12:24 -07002273 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002274 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002275
2276 // Changing RTP header extensions will recreate the AudioSendStream.
2277 send_parameters_.extensions.clear();
solenberg059fb442016-10-26 05:12:24 -07002278 SetSendParameters(send_parameters_);
solenberg2100c0b2017-03-01 11:29:29 -08002279 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
solenberg6d6e7c52016-04-13 09:07:30 -07002280}
2281
solenberg1ac56142015-10-13 03:58:19 -07002282// Test that we can create a channel and start playing out on it.
2283TEST_F(WebRtcVoiceEngineTestFake, Playout) {
solenbergff976312016-03-30 23:28:51 -07002284 EXPECT_TRUE(SetupRecvStream());
solenberg1ac56142015-10-13 03:58:19 -07002285 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
aleloi84ef6152016-08-04 05:28:21 -07002286 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002287 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi84ef6152016-08-04 05:28:21 -07002288 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002289 EXPECT_FALSE(GetRecvStream(kSsrcX).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002290}
2291
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002292// Test that we can add and remove send streams.
2293TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
2294 SetupForMultiSendStream();
2295
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002296 // Set the global state for sending.
solenberg059fb442016-10-26 05:12:24 -07002297 SetSend(true);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002298
solenbergc96df772015-10-21 13:01:53 -07002299 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002300 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002301 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002302 SetAudioSend(ssrc, true, &fake_source_);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002303 // Verify that we are in a sending state for all the created streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002304 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002305 }
tfarina5237aaf2015-11-10 23:44:30 -08002306 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002307
solenbergc96df772015-10-21 13:01:53 -07002308 // Delete the send streams.
2309 for (uint32_t ssrc : kSsrcs4) {
2310 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
solenberg3a941542015-11-16 07:34:50 -08002311 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
solenbergc96df772015-10-21 13:01:53 -07002312 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002313 }
solenbergc96df772015-10-21 13:01:53 -07002314 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002315}
2316
2317// Test SetSendCodecs correctly configure the codecs in all send streams.
2318TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
2319 SetupForMultiSendStream();
2320
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002321 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002322 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002323 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002324 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002325 }
2326
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002327 cricket::AudioSendParameters parameters;
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002328 // Set ISAC(16K) and CN(16K). VAD should be activated.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002329 parameters.codecs.push_back(kIsacCodec);
2330 parameters.codecs.push_back(kCn16000Codec);
2331 parameters.codecs[1].id = 97;
solenberg059fb442016-10-26 05:12:24 -07002332 SetSendParameters(parameters);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002333
2334 // Verify ISAC and VAD are corrected configured on all send channels.
solenbergc96df772015-10-21 13:01:53 -07002335 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002336 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2337 const auto& send_codec_spec =
2338 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2339 EXPECT_STREQ("ISAC", send_codec_spec.codec_inst.plname);
2340 EXPECT_EQ(send_codec_spec.codec_inst.plfreq, send_codec_spec.cng_plfreq);
2341 EXPECT_EQ(1, send_codec_spec.codec_inst.channels);
2342 EXPECT_EQ(97, send_codec_spec.cng_payload_type);
2343 EXPECT_EQ(webrtc::kFreq16000Hz, send_codec_spec.cng_plfreq);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002344 }
2345
minyue7a973442016-10-20 03:27:12 -07002346 // Change to PCMU(8K) and CN(16K).
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002347 parameters.codecs[0] = kPcmuCodec;
solenberg059fb442016-10-26 05:12:24 -07002348 SetSendParameters(parameters);
solenbergc96df772015-10-21 13:01:53 -07002349 for (uint32_t ssrc : kSsrcs4) {
minyue7a973442016-10-20 03:27:12 -07002350 ASSERT_TRUE(call_.GetAudioSendStream(ssrc) != nullptr);
2351 const auto& send_codec_spec =
2352 call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
2353 EXPECT_STREQ("PCMU", send_codec_spec.codec_inst.plname);
ossu0c4b8492017-03-02 11:03:25 -08002354 EXPECT_EQ(-1, send_codec_spec.cng_payload_type);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002355 }
2356}
2357
2358// Test we can SetSend on all send streams correctly.
2359TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2360 SetupForMultiSendStream();
2361
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002362 // Create the send channels and they should be a "not sending" date.
solenbergc96df772015-10-21 13:01:53 -07002363 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002364 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002365 cricket::StreamParams::CreateLegacy(ssrc)));
solenberg059fb442016-10-26 05:12:24 -07002366 SetAudioSend(ssrc, true, &fake_source_);
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002367 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002368 }
2369
2370 // Set the global state for starting sending.
solenberg059fb442016-10-26 05:12:24 -07002371 SetSend(true);
solenbergc96df772015-10-21 13:01:53 -07002372 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002373 // Verify that we are in a sending state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002374 EXPECT_TRUE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002375 }
2376
2377 // Set the global state for stopping sending.
solenberg059fb442016-10-26 05:12:24 -07002378 SetSend(false);
solenbergc96df772015-10-21 13:01:53 -07002379 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002380 // Verify that we are in a stop state for all the send streams.
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08002381 EXPECT_FALSE(GetSendStream(ssrc).IsSending());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002382 }
2383}
2384
2385// Test we can set the correct statistics on all send streams.
2386TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2387 SetupForMultiSendStream();
2388
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002389 // Create send streams.
solenbergc96df772015-10-21 13:01:53 -07002390 for (uint32_t ssrc : kSsrcs4) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002391 EXPECT_TRUE(channel_->AddSendStream(
solenbergc96df772015-10-21 13:01:53 -07002392 cricket::StreamParams::CreateLegacy(ssrc)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002393 }
solenberg85a04962015-10-27 03:35:21 -07002394
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002395 // Create a receive stream to check that none of the send streams end up in
2396 // the receive stream stats.
solenberg2100c0b2017-03-01 11:29:29 -08002397 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg971cab02016-06-14 10:02:41 -07002398
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002399 // We need send codec to be set to get all stats.
solenberg059fb442016-10-26 05:12:24 -07002400 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002401 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002402 SetAudioSendStreamStats();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002403
solenberg85a04962015-10-27 03:35:21 -07002404 // Check stats for the added streams.
2405 {
2406 cricket::VoiceMediaInfo info;
2407 EXPECT_EQ(true, channel_->GetStats(&info));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002408
solenberg85a04962015-10-27 03:35:21 -07002409 // We have added 4 send streams. We should see empty stats for all.
tfarina5237aaf2015-11-10 23:44:30 -08002410 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002411 for (const auto& sender : info.senders) {
solenberg566ef242015-11-06 15:34:49 -08002412 VerifyVoiceSenderInfo(sender, false);
solenberg85a04962015-10-27 03:35:21 -07002413 }
hbos1acfbd22016-11-17 23:43:29 -08002414 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002415
2416 // We have added one receive stream. We should see empty stats.
2417 EXPECT_EQ(info.receivers.size(), 1u);
2418 EXPECT_EQ(info.receivers[0].ssrc(), 0);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002419 }
solenberg1ac56142015-10-13 03:58:19 -07002420
solenberg2100c0b2017-03-01 11:29:29 -08002421 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002422 {
2423 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002424 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002425 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002426 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002427 EXPECT_EQ(0u, info.receivers.size());
2428 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002429
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002430 // Deliver a new packet - a default receive stream should be created and we
2431 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002432 {
2433 cricket::VoiceMediaInfo info;
2434 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2435 SetAudioReceiveStreamStats();
2436 EXPECT_EQ(true, channel_->GetStats(&info));
tfarina5237aaf2015-11-10 23:44:30 -08002437 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
solenberg85a04962015-10-27 03:35:21 -07002438 EXPECT_EQ(1u, info.receivers.size());
2439 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002440 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002441 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002442}
2443
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002444// Test that we can add and remove receive streams, and do proper send/playout.
2445// We can receive on multiple streams while sending one stream.
2446TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002447 EXPECT_TRUE(SetupSendStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448
solenberg1ac56142015-10-13 03:58:19 -07002449 // Start playout without a receive stream.
solenberg059fb442016-10-26 05:12:24 -07002450 SetSendParameters(send_parameters_);
aleloi84ef6152016-08-04 05:28:21 -07002451 channel_->SetPlayout(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002452
solenberg1ac56142015-10-13 03:58:19 -07002453 // Adding another stream should enable playout on the new stream only.
solenberg2100c0b2017-03-01 11:29:29 -08002454 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002455 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002456 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457
solenberg1ac56142015-10-13 03:58:19 -07002458 // Make sure only the new stream is played out.
solenberg2100c0b2017-03-01 11:29:29 -08002459 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002460
2461 // Adding yet another stream should have stream 2 and 3 enabled for playout.
solenberg2100c0b2017-03-01 11:29:29 -08002462 EXPECT_TRUE(AddRecvStream(kSsrcZ));
2463 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2464 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002465
2466 // Stop sending.
solenberg059fb442016-10-26 05:12:24 -07002467 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002468 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469
2470 // Stop playout.
aleloi84ef6152016-08-04 05:28:21 -07002471 channel_->SetPlayout(false);
solenberg2100c0b2017-03-01 11:29:29 -08002472 EXPECT_FALSE(GetRecvStream(kSsrcY).started());
2473 EXPECT_FALSE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474
aleloi84ef6152016-08-04 05:28:21 -07002475 // Restart playout and make sure recv streams are played out.
2476 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08002477 EXPECT_TRUE(GetRecvStream(kSsrcY).started());
2478 EXPECT_TRUE(GetRecvStream(kSsrcZ).started());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479
aleloi84ef6152016-08-04 05:28:21 -07002480 // Now remove the recv streams.
solenberg2100c0b2017-03-01 11:29:29 -08002481 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcZ));
2482 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002483}
2484
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485// Test that we can create a channel configured for Codian bridges,
solenberg1ac56142015-10-13 03:58:19 -07002486// and start sending on it.
2487TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
solenbergff976312016-03-30 23:28:51 -07002488 EXPECT_TRUE(SetupSendStream());
solenberg76377c52017-02-21 00:54:31 -08002489 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2490 EXPECT_CALL(apm_gc_,
2491 set_target_level_dbfs(11)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002492 SetSendParameters(send_parameters_);
2493 SetSend(true);
solenberg2100c0b2017-03-01 11:29:29 -08002494 EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
solenberg059fb442016-10-26 05:12:24 -07002495 SetSend(false);
solenberg2100c0b2017-03-01 11:29:29 -08002496 EXPECT_FALSE(GetSendStream(kSsrcX).IsSending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497}
2498
wu@webrtc.org97077a32013-10-25 21:18:33 +00002499TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002500 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002501 EXPECT_CALL(adm_,
2502 BuiltInAGCIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08002503 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
2504 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002505 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2506 send_parameters_.options.tx_agc_digital_compression_gain =
2507 rtc::Optional<uint16_t>(9);
2508 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2509 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08002510 EXPECT_CALL(apm_gc_, set_target_level_dbfs(3)).WillOnce(Return(0));
2511 EXPECT_CALL(apm_gc_, set_compression_gain_db(9)).WillRepeatedly(Return(0));
2512 EXPECT_CALL(apm_gc_, enable_limiter(true)).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002513 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002514
2515 // Check interaction with adjust_agc_delta. Both should be respected, for
2516 // backwards compatibility.
solenberg246b8172015-12-08 09:50:23 -08002517 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
solenberg76377c52017-02-21 00:54:31 -08002518 EXPECT_CALL(apm_gc_, set_target_level_dbfs(13)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07002519 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002520}
2521
wu@webrtc.org97077a32013-10-25 21:18:33 +00002522TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
solenbergff976312016-03-30 23:28:51 -07002523 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002524 EXPECT_CALL(adm_, SetRecordingSampleRate(48000)).WillOnce(Return(0));
2525 EXPECT_CALL(adm_, SetPlayoutSampleRate(44100)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08002526 send_parameters_.options.recording_sample_rate =
2527 rtc::Optional<uint32_t>(48000);
2528 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
solenberg059fb442016-10-26 05:12:24 -07002529 SetSendParameters(send_parameters_);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002530}
2531
minyue6b825df2016-10-31 04:08:32 -07002532TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) {
2533 EXPECT_TRUE(SetupSendStream());
2534 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2535 send_parameters_.options.audio_network_adaptor_config =
2536 rtc::Optional<std::string>("1234");
2537 SetSendParameters(send_parameters_);
2538 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002539 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002540}
2541
2542TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) {
2543 EXPECT_TRUE(SetupSendStream());
2544 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2545 send_parameters_.options.audio_network_adaptor_config =
2546 rtc::Optional<std::string>("1234");
2547 SetSendParameters(send_parameters_);
2548 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002549 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002550 const int initial_num = call_.GetNumCreatedSendStreams();
2551 cricket::AudioOptions options;
2552 options.audio_network_adaptor = rtc::Optional<bool>(false);
solenberg2100c0b2017-03-01 11:29:29 -08002553 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002554 // AudioSendStream expected to be recreated.
2555 EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams());
solenberg2100c0b2017-03-01 11:29:29 -08002556 EXPECT_EQ(rtc::Optional<std::string>(), GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002557}
2558
2559TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
2560 EXPECT_TRUE(SetupSendStream());
2561 send_parameters_.options.audio_network_adaptor = rtc::Optional<bool>(true);
2562 send_parameters_.options.audio_network_adaptor_config =
2563 rtc::Optional<std::string>("1234");
2564 SetSendParameters(send_parameters_);
2565 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002566 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002567 const int initial_num = call_.GetNumCreatedSendStreams();
2568 cricket::AudioOptions options;
2569 options.audio_network_adaptor = rtc::Optional<bool>();
2570 // Unvalued |options.audio_network_adaptor|.should not reset audio network
2571 // adaptor.
solenberg2100c0b2017-03-01 11:29:29 -08002572 SetAudioSend(kSsrcX, true, nullptr, &options);
minyue6b825df2016-10-31 04:08:32 -07002573 // AudioSendStream not expected to be recreated.
2574 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2575 EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config,
solenberg2100c0b2017-03-01 11:29:29 -08002576 GetAudioNetworkAdaptorConfig(kSsrcX));
minyue6b825df2016-10-31 04:08:32 -07002577}
2578
michaelt6672b262017-01-11 10:17:59 -08002579class WebRtcVoiceEngineWithSendSideBweWithOverheadTest
2580 : public WebRtcVoiceEngineTestFake {
2581 public:
2582 WebRtcVoiceEngineWithSendSideBweWithOverheadTest()
2583 : WebRtcVoiceEngineTestFake(
2584 "WebRTC-Audio-SendSideBwe/Enabled/WebRTC-SendSideBwe-WithOverhead/"
2585 "Enabled/") {}
2586};
2587
2588TEST_F(WebRtcVoiceEngineWithSendSideBweWithOverheadTest, MinAndMaxBitrate) {
2589 EXPECT_TRUE(SetupSendStream());
2590 cricket::AudioSendParameters parameters;
2591 parameters.codecs.push_back(kOpusCodec);
2592 SetSendParameters(parameters);
2593 const int initial_num = call_.GetNumCreatedSendStreams();
2594 EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams());
2595
2596 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
2597 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
ossu11bfc532017-02-16 05:37:06 -08002598 constexpr int kOpusMaxPtimeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
2599 constexpr int kMinOverheadBps =
2600 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002601 constexpr int kMaxOverheadBps = kOverheadPerPacket * 8 * 1000 / 10;
2602
2603 constexpr int kOpusMinBitrateBps = 6000;
2604 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002605 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002606 constexpr int kOpusBitrateFbBps = 32000;
2607 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadBps,
solenberg2100c0b2017-03-01 11:29:29 -08002608 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002609
2610 parameters.options.audio_network_adaptor = rtc::Optional<bool>(true);
2611 parameters.options.audio_network_adaptor_config =
2612 rtc::Optional<std::string>("1234");
2613 SetSendParameters(parameters);
2614
ossu11bfc532017-02-16 05:37:06 -08002615 constexpr int kMinOverheadWithAnaBps =
2616 kOverheadPerPacket * 8 * 1000 / kOpusMaxPtimeMs;
michaelt6672b262017-01-11 10:17:59 -08002617 constexpr int kMaxOverheadWithAnaBps = kOverheadPerPacket * 8 * 1000 / 20;
2618
2619 EXPECT_EQ(kOpusMinBitrateBps + kMinOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002620 GetSendStreamConfig(kSsrcX).min_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002621
2622 EXPECT_EQ(kOpusBitrateFbBps + kMaxOverheadWithAnaBps,
solenberg2100c0b2017-03-01 11:29:29 -08002623 GetSendStreamConfig(kSsrcX).max_bitrate_bps);
michaelt6672b262017-01-11 10:17:59 -08002624}
2625
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626// Test that we can set the outgoing SSRC properly.
solenbergff976312016-03-30 23:28:51 -07002627// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002628TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
solenbergff976312016-03-30 23:28:51 -07002629 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002630 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631}
2632
2633TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2634 // Setup. We need send codec to be set to get all stats.
solenbergff976312016-03-30 23:28:51 -07002635 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002636 // SetupSendStream adds a send stream with kSsrcX, so the receive
solenberg1ac56142015-10-13 03:58:19 -07002637 // stream has to use a different SSRC.
solenberg2100c0b2017-03-01 11:29:29 -08002638 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg059fb442016-10-26 05:12:24 -07002639 SetSendParameters(send_parameters_);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002640 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
solenberg971cab02016-06-14 10:02:41 -07002641 SetAudioSendStreamStats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642
solenberg85a04962015-10-27 03:35:21 -07002643 // Check stats for the added streams.
2644 {
2645 cricket::VoiceMediaInfo info;
2646 EXPECT_EQ(true, channel_->GetStats(&info));
2647
2648 // We have added one send stream. We should see the stats we've set.
2649 EXPECT_EQ(1u, info.senders.size());
solenberg566ef242015-11-06 15:34:49 -08002650 VerifyVoiceSenderInfo(info.senders[0], false);
solenberg85a04962015-10-27 03:35:21 -07002651 // We have added one receive stream. We should see empty stats.
2652 EXPECT_EQ(info.receivers.size(), 1u);
2653 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2654 }
solenberg1ac56142015-10-13 03:58:19 -07002655
solenberg566ef242015-11-06 15:34:49 -08002656 // Start sending - this affects some reported stats.
2657 {
2658 cricket::VoiceMediaInfo info;
solenberg059fb442016-10-26 05:12:24 -07002659 SetSend(true);
solenberg566ef242015-11-06 15:34:49 -08002660 EXPECT_EQ(true, channel_->GetStats(&info));
2661 VerifyVoiceSenderInfo(info.senders[0], true);
hbos1acfbd22016-11-17 23:43:29 -08002662 VerifyVoiceSendRecvCodecs(info);
solenberg566ef242015-11-06 15:34:49 -08002663 }
2664
solenberg2100c0b2017-03-01 11:29:29 -08002665 // Remove the kSsrcY stream. No receiver stats.
solenberg85a04962015-10-27 03:35:21 -07002666 {
2667 cricket::VoiceMediaInfo info;
solenberg2100c0b2017-03-01 11:29:29 -08002668 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcY));
solenberg85a04962015-10-27 03:35:21 -07002669 EXPECT_EQ(true, channel_->GetStats(&info));
2670 EXPECT_EQ(1u, info.senders.size());
2671 EXPECT_EQ(0u, info.receivers.size());
2672 }
solenberg1ac56142015-10-13 03:58:19 -07002673
Fredrik Solenberg4f4ec0a2015-10-22 10:49:27 +02002674 // Deliver a new packet - a default receive stream should be created and we
2675 // should see stats again.
solenberg85a04962015-10-27 03:35:21 -07002676 {
2677 cricket::VoiceMediaInfo info;
2678 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2679 SetAudioReceiveStreamStats();
2680 EXPECT_EQ(true, channel_->GetStats(&info));
2681 EXPECT_EQ(1u, info.senders.size());
2682 EXPECT_EQ(1u, info.receivers.size());
2683 VerifyVoiceReceiverInfo(info.receivers[0]);
hbos1acfbd22016-11-17 23:43:29 -08002684 VerifyVoiceSendRecvCodecs(info);
solenberg85a04962015-10-27 03:35:21 -07002685 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002686}
2687
2688// Test that we can set the outgoing SSRC properly with multiple streams.
solenbergff976312016-03-30 23:28:51 -07002689// SSRC is set in SetupSendStream() by calling AddSendStream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002691 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08002692 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2693 EXPECT_TRUE(AddRecvStream(kSsrcY));
2694 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002695}
2696
2697// Test that the local SSRC is the same on sending and receiving channels if the
2698// receive channel is created before the send channel.
2699TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
solenbergff976312016-03-30 23:28:51 -07002700 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08002701 EXPECT_TRUE(AddRecvStream(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002702 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08002703 cricket::StreamParams::CreateLegacy(kSsrcX)));
2704 EXPECT_TRUE(call_.GetAudioSendStream(kSsrcX));
2705 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002706}
2707
2708// Test that we can properly receive packets.
2709TEST_F(WebRtcVoiceEngineTestFake, Recv) {
solenbergff976312016-03-30 23:28:51 -07002710 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002711 EXPECT_TRUE(AddRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002712 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002713
2714 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2715 sizeof(kPcmuFrame)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002716}
2717
2718// Test that we can properly receive packets on multiple streams.
2719TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
solenbergff976312016-03-30 23:28:51 -07002720 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002721 const uint32_t ssrc1 = 1;
2722 const uint32_t ssrc2 = 2;
2723 const uint32_t ssrc3 = 3;
solenberg8189b022016-06-14 12:13:00 -07002724 EXPECT_TRUE(AddRecvStream(ssrc1));
2725 EXPECT_TRUE(AddRecvStream(ssrc2));
2726 EXPECT_TRUE(AddRecvStream(ssrc3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002727 // Create packets with the right SSRCs.
mflodman3d7db262016-04-29 00:57:13 -07002728 unsigned char packets[4][sizeof(kPcmuFrame)];
tfarina5237aaf2015-11-10 23:44:30 -08002729 for (size_t i = 0; i < arraysize(packets); ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
Peter Boström0c4e06b2015-10-07 12:23:21 +02002731 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002732 }
mflodman3d7db262016-04-29 00:57:13 -07002733
2734 const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1);
2735 const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2);
2736 const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3);
2737
2738 EXPECT_EQ(s1.received_packets(), 0);
2739 EXPECT_EQ(s2.received_packets(), 0);
2740 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002741
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002742 DeliverPacket(packets[0], sizeof(packets[0]));
mflodman3d7db262016-04-29 00:57:13 -07002743 EXPECT_EQ(s1.received_packets(), 0);
2744 EXPECT_EQ(s2.received_packets(), 0);
2745 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002746
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002747 DeliverPacket(packets[1], sizeof(packets[1]));
mflodman3d7db262016-04-29 00:57:13 -07002748 EXPECT_EQ(s1.received_packets(), 1);
2749 EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1])));
2750 EXPECT_EQ(s2.received_packets(), 0);
2751 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002752
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002753 DeliverPacket(packets[2], sizeof(packets[2]));
mflodman3d7db262016-04-29 00:57:13 -07002754 EXPECT_EQ(s1.received_packets(), 1);
2755 EXPECT_EQ(s2.received_packets(), 1);
2756 EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2])));
2757 EXPECT_EQ(s3.received_packets(), 0);
solenberg7e63ef02015-11-20 00:19:43 -08002758
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759 DeliverPacket(packets[3], sizeof(packets[3]));
mflodman3d7db262016-04-29 00:57:13 -07002760 EXPECT_EQ(s1.received_packets(), 1);
2761 EXPECT_EQ(s2.received_packets(), 1);
2762 EXPECT_EQ(s3.received_packets(), 1);
2763 EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3])));
solenberg7e63ef02015-11-20 00:19:43 -08002764
mflodman3d7db262016-04-29 00:57:13 -07002765 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3));
2766 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2));
2767 EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768}
2769
solenberg2100c0b2017-03-01 11:29:29 -08002770// Test that receiving on an unsignaled stream works (a stream is created).
2771TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002772 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002773 EXPECT_EQ(0, call_.GetAudioReceiveStreams().size());
2774
solenberg7e63ef02015-11-20 00:19:43 -08002775 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
mflodman3d7db262016-04-29 00:57:13 -07002776
2777 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002778 EXPECT_TRUE(GetRecvStream(kSsrc1).VerifyLastPacket(kPcmuFrame,
2779 sizeof(kPcmuFrame)));
solenberg7e63ef02015-11-20 00:19:43 -08002780}
2781
solenberg2100c0b2017-03-01 11:29:29 -08002782// Test that receiving N unsignaled stream works (streams will be created), and
2783// that packets are forwarded to them all.
2784TEST_F(WebRtcVoiceEngineTestFake, RecvMultipleUnsignaled) {
solenbergff976312016-03-30 23:28:51 -07002785 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002786 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002787 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2788
solenberg2100c0b2017-03-01 11:29:29 -08002789 // Note that SSRC = 0 is not supported.
solenbergebb349d2017-03-13 05:46:15 -07002790 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg7e63ef02015-11-20 00:19:43 -08002791 rtc::SetBE32(&packet[8], ssrc);
2792 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002793
solenberg2100c0b2017-03-01 11:29:29 -08002794 // Verify we have one new stream for each loop iteration.
2795 EXPECT_EQ(ssrc, call_.GetAudioReceiveStreams().size());
mflodman3d7db262016-04-29 00:57:13 -07002796 EXPECT_EQ(1, GetRecvStream(ssrc).received_packets());
2797 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
solenberg7e63ef02015-11-20 00:19:43 -08002798 }
mflodman3d7db262016-04-29 00:57:13 -07002799
solenberg2100c0b2017-03-01 11:29:29 -08002800 // Sending on the same SSRCs again should not create new streams.
solenbergebb349d2017-03-13 05:46:15 -07002801 for (uint32_t ssrc = 1; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc) {
solenberg2100c0b2017-03-01 11:29:29 -08002802 rtc::SetBE32(&packet[8], ssrc);
2803 DeliverPacket(packet, sizeof(packet));
2804
solenbergebb349d2017-03-13 05:46:15 -07002805 EXPECT_EQ(kMaxUnsignaledRecvStreams, call_.GetAudioReceiveStreams().size());
solenberg2100c0b2017-03-01 11:29:29 -08002806 EXPECT_EQ(2, GetRecvStream(ssrc).received_packets());
2807 EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet)));
2808 }
2809
2810 // Send on another SSRC, the oldest unsignaled stream (SSRC=1) is replaced.
2811 constexpr uint32_t kAnotherSsrc = 667;
2812 rtc::SetBE32(&packet[8], kAnotherSsrc);
mflodman3d7db262016-04-29 00:57:13 -07002813 DeliverPacket(packet, sizeof(packet));
solenberg2100c0b2017-03-01 11:29:29 -08002814
2815 const auto& streams = call_.GetAudioReceiveStreams();
solenbergebb349d2017-03-13 05:46:15 -07002816 EXPECT_EQ(kMaxUnsignaledRecvStreams, streams.size());
solenberg2100c0b2017-03-01 11:29:29 -08002817 size_t i = 0;
solenbergebb349d2017-03-13 05:46:15 -07002818 for (uint32_t ssrc = 2; ssrc < (1 + kMaxUnsignaledRecvStreams); ++ssrc, ++i) {
solenberg2100c0b2017-03-01 11:29:29 -08002819 EXPECT_EQ(ssrc, streams[i]->GetConfig().rtp.remote_ssrc);
2820 EXPECT_EQ(2, streams[i]->received_packets());
2821 }
2822 EXPECT_EQ(kAnotherSsrc, streams[i]->GetConfig().rtp.remote_ssrc);
2823 EXPECT_EQ(1, streams[i]->received_packets());
2824 // Sanity check that we've checked all streams.
solenbergebb349d2017-03-13 05:46:15 -07002825 EXPECT_EQ(kMaxUnsignaledRecvStreams, (i + 1));
solenberg7e63ef02015-11-20 00:19:43 -08002826}
2827
solenberg2100c0b2017-03-01 11:29:29 -08002828// Test that a default channel is created even after a signaled stream has been
solenberg7e63ef02015-11-20 00:19:43 -08002829// added, and that this stream will get any packets for unknown SSRCs.
solenberg2100c0b2017-03-01 11:29:29 -08002830TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignaledAfterSignaled) {
solenbergff976312016-03-30 23:28:51 -07002831 EXPECT_TRUE(SetupChannel());
mflodman3d7db262016-04-29 00:57:13 -07002832 unsigned char packet[sizeof(kPcmuFrame)];
solenberg7e63ef02015-11-20 00:19:43 -08002833 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2834
2835 // Add a known stream, send packet and verify we got it.
mflodman3d7db262016-04-29 00:57:13 -07002836 const uint32_t signaled_ssrc = 1;
2837 rtc::SetBE32(&packet[8], signaled_ssrc);
solenberg8189b022016-06-14 12:13:00 -07002838 EXPECT_TRUE(AddRecvStream(signaled_ssrc));
solenberg7e63ef02015-11-20 00:19:43 -08002839 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002840 EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket(
2841 packet, sizeof(packet)));
solenberg2100c0b2017-03-01 11:29:29 -08002842 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002843
2844 // Note that the first unknown SSRC cannot be 0, because we only support
2845 // creating receive streams for SSRC!=0.
mflodman3d7db262016-04-29 00:57:13 -07002846 const uint32_t unsignaled_ssrc = 7011;
2847 rtc::SetBE32(&packet[8], unsignaled_ssrc);
solenberg7e63ef02015-11-20 00:19:43 -08002848 DeliverPacket(packet, sizeof(packet));
mflodman3d7db262016-04-29 00:57:13 -07002849 EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket(
2850 packet, sizeof(packet)));
2851 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2852
2853 DeliverPacket(packet, sizeof(packet));
2854 EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets());
2855
2856 rtc::SetBE32(&packet[8], signaled_ssrc);
2857 DeliverPacket(packet, sizeof(packet));
2858 EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets());
2859 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
solenberg7e63ef02015-11-20 00:19:43 -08002860}
2861
solenberg4904fb62017-02-17 12:01:14 -08002862// Two tests to verify that adding a receive stream with the same SSRC as a
2863// previously added unsignaled stream will only recreate underlying stream
2864// objects if the stream parameters have changed.
2865TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_NoRecreate) {
2866 EXPECT_TRUE(SetupChannel());
2867
2868 // Spawn unsignaled stream with SSRC=1.
2869 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2870 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2871 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2872 sizeof(kPcmuFrame)));
2873
2874 // Verify that the underlying stream object in Call is not recreated when a
2875 // stream with SSRC=1 is added.
2876 const auto& streams = call_.GetAudioReceiveStreams();
2877 EXPECT_EQ(1, streams.size());
2878 int audio_receive_stream_id = streams.front()->id();
2879 EXPECT_TRUE(AddRecvStream(1));
2880 EXPECT_EQ(1, streams.size());
2881 EXPECT_EQ(audio_receive_stream_id, streams.front()->id());
2882}
2883
2884TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamAfterUnsignaled_Recreate) {
2885 EXPECT_TRUE(SetupChannel());
2886
2887 // Spawn unsignaled stream with SSRC=1.
2888 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2889 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
2890 EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame,
2891 sizeof(kPcmuFrame)));
2892
2893 // Verify that the underlying stream object in Call *is* recreated when a
2894 // stream with SSRC=1 is added, and which has changed stream parameters.
2895 const auto& streams = call_.GetAudioReceiveStreams();
2896 EXPECT_EQ(1, streams.size());
2897 int audio_receive_stream_id = streams.front()->id();
2898 cricket::StreamParams stream_params;
2899 stream_params.ssrcs.push_back(1);
2900 stream_params.sync_label = "sync_label";
2901 EXPECT_TRUE(channel_->AddRecvStream(stream_params));
2902 EXPECT_EQ(1, streams.size());
2903 EXPECT_NE(audio_receive_stream_id, streams.front()->id());
2904}
2905
solenberg0a617e22015-10-20 15:49:38 -07002906// Test that we properly handle failures to add a receive stream.
2907TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002908 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002909 voe_.set_fail_create_channel(true);
solenberg8189b022016-06-14 12:13:00 -07002910 EXPECT_FALSE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002911}
2912
solenberg0a617e22015-10-20 15:49:38 -07002913// Test that we properly handle failures to add a send stream.
2914TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002915 EXPECT_TRUE(SetupChannel());
solenberg0a617e22015-10-20 15:49:38 -07002916 voe_.set_fail_create_channel(true);
2917 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2918}
2919
solenberg1ac56142015-10-13 03:58:19 -07002920// Test that AddRecvStream creates new stream.
2921TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
solenbergff976312016-03-30 23:28:51 -07002922 EXPECT_TRUE(SetupRecvStream());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002923 int channel_num = voe_.GetLastChannel();
solenberg8189b022016-06-14 12:13:00 -07002924 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002925 EXPECT_NE(channel_num, voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926}
2927
2928// Test that after adding a recv stream, we do not decode more codecs than
2929// those previously passed into SetRecvCodecs.
2930TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
solenbergff976312016-03-30 23:28:51 -07002931 EXPECT_TRUE(SetupSendStream());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 cricket::AudioRecvParameters parameters;
2933 parameters.codecs.push_back(kIsacCodec);
2934 parameters.codecs.push_back(kPcmuCodec);
2935 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
solenberg2100c0b2017-03-01 11:29:29 -08002936 EXPECT_TRUE(AddRecvStream(kSsrcX));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002937 int channel_num2 = voe_.GetLastChannel();
2938 webrtc::CodecInst gcodec;
tfarina5237aaf2015-11-10 23:44:30 -08002939 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002940 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002941 gcodec.channels = 2;
2942 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2943}
2944
2945// Test that we properly clean up any streams that were added, even if
2946// not explicitly removed.
2947TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
solenbergff976312016-03-30 23:28:51 -07002948 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07002949 SetSendParameters(send_parameters_);
solenberg8189b022016-06-14 12:13:00 -07002950 EXPECT_TRUE(AddRecvStream(1));
2951 EXPECT_TRUE(AddRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2953 delete channel_;
2954 channel_ = NULL;
2955 EXPECT_EQ(0, voe_.GetNumChannels());
2956}
2957
wu@webrtc.org78187522013-10-07 23:32:02 +00002958TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
solenbergff976312016-03-30 23:28:51 -07002959 EXPECT_TRUE(SetupSendStream());
solenberg8189b022016-06-14 12:13:00 -07002960 EXPECT_FALSE(AddRecvStream(0));
wu@webrtc.org78187522013-10-07 23:32:02 +00002961}
2962
2963TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
solenbergff976312016-03-30 23:28:51 -07002964 EXPECT_TRUE(SetupChannel());
solenberg8189b022016-06-14 12:13:00 -07002965 EXPECT_TRUE(AddRecvStream(1));
solenberg1ac56142015-10-13 03:58:19 -07002966 // Manually delete channel to simulate a failure.
2967 int channel = voe_.GetLastChannel();
2968 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2969 // Add recv stream 2 should work.
solenberg8189b022016-06-14 12:13:00 -07002970 EXPECT_TRUE(AddRecvStream(2));
wu@webrtc.org78187522013-10-07 23:32:02 +00002971 int new_channel = voe_.GetLastChannel();
solenberg1ac56142015-10-13 03:58:19 -07002972 EXPECT_NE(channel, new_channel);
2973 // The last created channel is deleted too.
2974 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
wu@webrtc.org78187522013-10-07 23:32:02 +00002975}
2976
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002977// Test the InsertDtmf on default send stream as caller.
2978TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
solenbergffbbcac2016-11-17 05:25:37 -08002979 TestInsertDtmf(0, true, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980}
2981
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002982// Test the InsertDtmf on default send stream as callee
2983TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
solenbergffbbcac2016-11-17 05:25:37 -08002984 TestInsertDtmf(0, false, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002985}
2986
2987// Test the InsertDtmf on specified send stream as caller.
2988TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
solenberg2100c0b2017-03-01 11:29:29 -08002989 TestInsertDtmf(kSsrcX, true, kTelephoneEventCodec2);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002990}
2991
2992// Test the InsertDtmf on specified send stream as callee.
2993TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
solenberg2100c0b2017-03-01 11:29:29 -08002994 TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995}
2996
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
solenbergff976312016-03-30 23:28:51 -07002998 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07002999 EXPECT_CALL(adm_,
3000 BuiltInAECIsAvailable()).Times(9).WillRepeatedly(Return(false));
3001 EXPECT_CALL(adm_,
3002 BuiltInAGCIsAvailable()).Times(4).WillRepeatedly(Return(false));
3003 EXPECT_CALL(adm_,
3004 BuiltInNSIsAvailable()).Times(2).WillRepeatedly(Return(false));
solenberg76377c52017-02-21 00:54:31 -08003005
solenberg246b8172015-12-08 09:50:23 -08003006 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3007 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008
solenberg246b8172015-12-08 09:50:23 -08003009 // Nothing set in AudioOptions, so everything should be as default.
3010 send_parameters_.options = cricket::AudioOptions();
solenberg059fb442016-10-26 05:12:24 -07003011 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003012 EXPECT_TRUE(IsHighPassFilterEnabled());
solenberg246b8172015-12-08 09:50:23 -08003013 EXPECT_EQ(50, voe_.GetNetEqCapacity());
3014 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015
3016 // Turn echo cancellation off
solenberg76377c52017-02-21 00:54:31 -08003017 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3018 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003019 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003020 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003021
3022 // Turn echo cancellation back on, with settings, and make sure
3023 // nothing else changed.
solenberg76377c52017-02-21 00:54:31 -08003024 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3025 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003026 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003027 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003029 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
3030 // control.
solenberg76377c52017-02-21 00:54:31 -08003031 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3032 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003033 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003034 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003035
3036 // Turn off echo cancellation and delay agnostic aec.
solenberg76377c52017-02-21 00:54:31 -08003037 EXPECT_CALL(apm_ec_, Enable(false)).WillOnce(Return(0));
3038 EXPECT_CALL(apm_ec_, enable_metrics(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003039 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
3040 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
3041 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003042 SetSendParameters(send_parameters_);
solenberg76377c52017-02-21 00:54:31 -08003043
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003044 // Turning delay agnostic aec back on should also turn on echo cancellation.
solenberg76377c52017-02-21 00:54:31 -08003045 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3046 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003047 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003048 SetSendParameters(send_parameters_);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01003049
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050 // Turn off AGC
solenberg76377c52017-02-21 00:54:31 -08003051 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3052 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3053 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3054 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003055 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
solenberg059fb442016-10-26 05:12:24 -07003056 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003057
3058 // Turn AGC back on
solenberg76377c52017-02-21 00:54:31 -08003059 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3060 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3061 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3062 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
solenberg246b8172015-12-08 09:50:23 -08003063 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
3064 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
solenberg059fb442016-10-26 05:12:24 -07003065 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003066
3067 // Turn off other options (and stereo swapping on).
solenberg76377c52017-02-21 00:54:31 -08003068 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3069 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3070 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3071 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3072 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3073 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3074 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg246b8172015-12-08 09:50:23 -08003075 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
3076 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
3077 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
3078 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
solenberg059fb442016-10-26 05:12:24 -07003079 SetSendParameters(send_parameters_);
peah8271d042016-11-22 07:24:52 -08003080 EXPECT_FALSE(IsHighPassFilterEnabled());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003081
solenberg1ac56142015-10-13 03:58:19 -07003082 // Set options again to ensure it has no impact.
solenberg76377c52017-02-21 00:54:31 -08003083 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3084 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3085 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3086 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3087 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
3088 EXPECT_CALL(apm_vd_, Enable(false)).WillOnce(Return(0));
3089 EXPECT_CALL(transmit_mixer_, EnableStereoChannelSwapping(true));
solenberg059fb442016-10-26 05:12:24 -07003090 SetSendParameters(send_parameters_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003091}
3092
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003093TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
solenbergff976312016-03-30 23:28:51 -07003094 EXPECT_TRUE(SetupSendStream());
solenberg5b5129a2016-04-08 05:35:48 -07003095 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003096 BuiltInAECIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003097 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003098 BuiltInAGCIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg5b5129a2016-04-08 05:35:48 -07003099 EXPECT_CALL(adm_,
solenberg76377c52017-02-21 00:54:31 -08003100 BuiltInNSIsAvailable()).Times(8).WillRepeatedly(Return(false));
solenberg059fb442016-10-26 05:12:24 -07003101 EXPECT_CALL(adm_,
3102 RecordingIsInitialized()).Times(2).WillRepeatedly(Return(false));
3103 EXPECT_CALL(adm_, Recording()).Times(2).WillRepeatedly(Return(false));
3104 EXPECT_CALL(adm_, InitRecording()).Times(2).WillRepeatedly(Return(0));
3105 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(10);
3106 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(10);
solenberg5b5129a2016-04-08 05:35:48 -07003107
kwiberg686a8ef2016-02-26 03:00:35 -08003108 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
solenbergbc37fc82016-04-04 09:54:44 -07003109 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003110 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
kwiberg686a8ef2016-02-26 03:00:35 -08003111 std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
solenbergbc37fc82016-04-04 09:54:44 -07003112 static_cast<cricket::WebRtcVoiceMediaChannel*>(engine_->CreateChannel(
nisse51542be2016-02-12 02:27:06 -08003113 &call_, cricket::MediaConfig(), cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003114
3115 // Have to add a stream to make SetSend work.
3116 cricket::StreamParams stream1;
3117 stream1.ssrcs.push_back(1);
3118 channel1->AddSendStream(stream1);
3119 cricket::StreamParams stream2;
3120 stream2.ssrcs.push_back(2);
3121 channel2->AddSendStream(stream2);
3122
3123 // AEC and AGC and NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003124 cricket::AudioSendParameters parameters_options_all = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003125 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
3126 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
3127 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
solenberg76377c52017-02-21 00:54:31 -08003128 EXPECT_CALL(adm_, SetAGC(true)).Times(2).WillRepeatedly(Return(0));
3129 EXPECT_CALL(apm_ec_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3130 EXPECT_CALL(apm_ec_, enable_metrics(true)).Times(2).WillRepeatedly(Return(0));
3131 EXPECT_CALL(apm_gc_, Enable(true)).Times(2).WillRepeatedly(Return(0));
3132 EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003133 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003134 EXPECT_EQ(parameters_options_all.options, channel1->options());
solenberg059fb442016-10-26 05:12:24 -07003135 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003136 EXPECT_EQ(parameters_options_all.options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003137
3138 // unset NS
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003140 parameters_options_no_ns.options.noise_suppression =
3141 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003142 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3143 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3144 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3145 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3146 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003147 EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003148 cricket::AudioOptions expected_options = parameters_options_all.options;
Karl Wibergbe579832015-11-10 22:34:18 +01003149 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3150 expected_options.auto_gain_control = rtc::Optional<bool>(true);
3151 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003152 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003153
3154 // unset AGC
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003155 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
Karl Wibergbe579832015-11-10 22:34:18 +01003156 parameters_options_no_agc.options.auto_gain_control =
3157 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003158 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3159 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3160 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3161 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3162 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003163 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
Karl Wibergbe579832015-11-10 22:34:18 +01003164 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3165 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3166 expected_options.noise_suppression = rtc::Optional<bool>(true);
solenberg66f43392015-09-09 01:36:22 -07003167 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003168
solenberg76377c52017-02-21 00:54:31 -08003169 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3170 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3171 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3172 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3173 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003174 EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003175
solenberg76377c52017-02-21 00:54:31 -08003176 EXPECT_CALL(adm_, SetAGC(true)).WillOnce(Return(0));
3177 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3178 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3179 EXPECT_CALL(apm_gc_, Enable(true)).WillOnce(Return(0));
3180 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003181 channel1->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003182
solenberg76377c52017-02-21 00:54:31 -08003183 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3184 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3185 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3186 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3187 EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003188 channel2->SetSend(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003189
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003190 // Make sure settings take effect while we are sending.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003191 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
3192 send_parameters_;
kwiberg102c6a62015-10-30 02:47:38 -07003193 parameters_options_no_agc_nor_ns.options.auto_gain_control =
Karl Wibergbe579832015-11-10 22:34:18 +01003194 rtc::Optional<bool>(false);
kwiberg102c6a62015-10-30 02:47:38 -07003195 parameters_options_no_agc_nor_ns.options.noise_suppression =
Karl Wibergbe579832015-11-10 22:34:18 +01003196 rtc::Optional<bool>(false);
solenberg76377c52017-02-21 00:54:31 -08003197 EXPECT_CALL(adm_, SetAGC(false)).WillOnce(Return(0));
3198 EXPECT_CALL(apm_ec_, Enable(true)).WillOnce(Return(0));
3199 EXPECT_CALL(apm_ec_, enable_metrics(true)).WillOnce(Return(0));
3200 EXPECT_CALL(apm_gc_, Enable(false)).WillOnce(Return(0));
3201 EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
solenberg059fb442016-10-26 05:12:24 -07003202 EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
Karl Wibergbe579832015-11-10 22:34:18 +01003203 expected_options.echo_cancellation = rtc::Optional<bool>(true);
3204 expected_options.auto_gain_control = rtc::Optional<bool>(false);
3205 expected_options.noise_suppression = rtc::Optional<bool>(false);
solenberg66f43392015-09-09 01:36:22 -07003206 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003207}
3208
wu@webrtc.orgde305012013-10-31 15:40:38 +00003209// This test verifies DSCP settings are properly applied on voice media channel.
3210TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
solenbergff976312016-03-30 23:28:51 -07003211 EXPECT_TRUE(SetupSendStream());
nisse51542be2016-02-12 02:27:06 -08003212 cricket::FakeNetworkInterface network_interface;
3213 cricket::MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003214 std::unique_ptr<cricket::VoiceMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003215
solenberg059fb442016-10-26 05:12:24 -07003216 EXPECT_CALL(apm_, ApplyConfig(testing::_)).Times(3);
3217 EXPECT_CALL(apm_, SetExtraOptions(testing::_)).Times(3);
3218
solenbergbc37fc82016-04-04 09:54:44 -07003219 channel.reset(
3220 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003221 channel->SetInterface(&network_interface);
3222 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3223 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3224
3225 config.enable_dscp = true;
solenbergbc37fc82016-04-04 09:54:44 -07003226 channel.reset(
3227 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003228 channel->SetInterface(&network_interface);
3229 EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
3230
3231 // Verify that setting the option to false resets the
3232 // DiffServCodePoint.
3233 config.enable_dscp = false;
solenbergbc37fc82016-04-04 09:54:44 -07003234 channel.reset(
3235 engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
nisse51542be2016-02-12 02:27:06 -08003236 channel->SetInterface(&network_interface);
3237 // Default value when DSCP is disabled should be DSCP_DEFAULT.
3238 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
3239
3240 channel->SetInterface(nullptr);
wu@webrtc.orgde305012013-10-31 15:40:38 +00003241}
3242
solenberg1ac56142015-10-13 03:58:19 -07003243TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
solenbergff976312016-03-30 23:28:51 -07003244 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003245 cricket::WebRtcVoiceMediaChannel* media_channel =
3246 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg1ac56142015-10-13 03:58:19 -07003247 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
solenberg2100c0b2017-03-01 11:29:29 -08003248 EXPECT_TRUE(AddRecvStream(kSsrcX));
solenberg1ac56142015-10-13 03:58:19 -07003249 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003250 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrcX));
3251 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrcY));
3252 EXPECT_TRUE(AddRecvStream(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003253 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003254 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255}
3256
solenberg1ac56142015-10-13 03:58:19 -07003257TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
solenbergff976312016-03-30 23:28:51 -07003258 EXPECT_TRUE(SetupChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003259 cricket::WebRtcVoiceMediaChannel* media_channel =
solenberg1ac56142015-10-13 03:58:19 -07003260 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3261 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
3262 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003263 cricket::StreamParams::CreateLegacy(kSsrcX)));
solenberg1ac56142015-10-13 03:58:19 -07003264 int channel_id = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003265 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrcX));
3266 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrcY));
solenberg1ac56142015-10-13 03:58:19 -07003267 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003268 cricket::StreamParams::CreateLegacy(kSsrcY)));
solenberg1ac56142015-10-13 03:58:19 -07003269 int channel_id2 = voe_.GetLastChannel();
solenberg2100c0b2017-03-01 11:29:29 -08003270 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrcY));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003271}
3272
solenberg4bac9c52015-10-09 02:32:53 -07003273TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
solenbergff976312016-03-30 23:28:51 -07003274 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003275 EXPECT_FALSE(channel_->SetOutputVolume(kSsrcY, 0.5));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003276 cricket::StreamParams stream;
solenberg2100c0b2017-03-01 11:29:29 -08003277 stream.ssrcs.push_back(kSsrcY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003278 EXPECT_TRUE(channel_->AddRecvStream(stream));
solenberg2100c0b2017-03-01 11:29:29 -08003279 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrcY).gain());
3280 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcY, 3));
3281 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcY).gain());
solenberg1ac56142015-10-13 03:58:19 -07003282}
3283
solenberg2100c0b2017-03-01 11:29:29 -08003284TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003285 EXPECT_TRUE(SetupChannel());
solenberg2100c0b2017-03-01 11:29:29 -08003286
3287 // Spawn an unsignaled stream by sending a packet - gain should be 1.
solenberg1ac56142015-10-13 03:58:19 -07003288 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003289 EXPECT_DOUBLE_EQ(1, GetRecvStream(kSsrc1).gain());
3290
3291 // Should remember the volume "2" which will be set on new unsignaled streams,
3292 // and also set the gain to 2 on existing unsignaled streams.
3293 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2));
3294 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain());
3295
3296 // Spawn an unsignaled stream by sending a packet - gain should be 2.
3297 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3298 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3299 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3300 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
3301 EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain());
3302
3303 // Setting gain with SSRC=0 should affect all unsignaled streams.
3304 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3));
solenbergebb349d2017-03-13 05:46:15 -07003305 if (kMaxUnsignaledRecvStreams > 1) {
3306 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3307 }
solenberg2100c0b2017-03-01 11:29:29 -08003308 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrcX).gain());
3309
3310 // Setting gain on an individual stream affects only that.
3311 EXPECT_TRUE(channel_->SetOutputVolume(kSsrcX, 4));
solenbergebb349d2017-03-13 05:46:15 -07003312 if (kMaxUnsignaledRecvStreams > 1) {
3313 EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain());
3314 }
solenberg2100c0b2017-03-01 11:29:29 -08003315 EXPECT_DOUBLE_EQ(4, GetRecvStream(kSsrcX).gain());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003316}
3317
pbos8fc7fa72015-07-15 08:02:58 -07003318TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003319 const uint32_t kAudioSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07003320 const std::string kSyncLabel = "AvSyncLabel";
3321
solenbergff976312016-03-30 23:28:51 -07003322 EXPECT_TRUE(SetupSendStream());
pbos8fc7fa72015-07-15 08:02:58 -07003323 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3324 sp.sync_label = kSyncLabel;
3325 // Creating two channels to make sure that sync label is set properly for both
3326 // the default voice channel and following ones.
3327 EXPECT_TRUE(channel_->AddRecvStream(sp));
3328 sp.ssrcs[0] += 1;
3329 EXPECT_TRUE(channel_->AddRecvStream(sp));
3330
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003331 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003332 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003333 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003334 << "SyncGroup should be set based on sync_label";
3335 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003336 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003337 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003338}
3339
solenberg3a941542015-11-16 07:34:50 -08003340// TODO(solenberg): Remove, once recv streams are configured through Call.
3341// (This is then covered by TestSetRecvRtpHeaderExtensions.)
pbos6bb1b6e2015-07-24 07:10:18 -07003342TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003343 // Test that setting the header extensions results in the expected state
3344 // changes on an associated Call.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003345 std::vector<uint32_t> ssrcs;
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003346 ssrcs.push_back(223);
3347 ssrcs.push_back(224);
3348
solenbergff976312016-03-30 23:28:51 -07003349 EXPECT_TRUE(SetupSendStream());
solenberg059fb442016-10-26 05:12:24 -07003350 SetSendParameters(send_parameters_);
Peter Boström0c4e06b2015-10-07 12:23:21 +02003351 for (uint32_t ssrc : ssrcs) {
solenberg059fb442016-10-26 05:12:24 -07003352 EXPECT_TRUE(channel_->AddRecvStream(
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003353 cricket::StreamParams::CreateLegacy(ssrc)));
3354 }
3355
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003356 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003357 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003358 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003359 EXPECT_NE(nullptr, s);
3360 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3361 }
3362
3363 // Set up receive extensions.
solenbergbc37fc82016-04-04 09:54:44 -07003364 cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003365 cricket::AudioRecvParameters recv_parameters;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003366 recv_parameters.extensions = capabilities.header_extensions;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003367 channel_->SetRecvParameters(recv_parameters);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003368 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003369 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003370 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003371 EXPECT_NE(nullptr, s);
3372 const auto& s_exts = s->GetConfig().rtp.extensions;
Stefan Holmer9d69c3f2015-12-07 10:45:43 +01003373 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3374 for (const auto& e_ext : capabilities.header_extensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003375 for (const auto& s_ext : s_exts) {
3376 if (e_ext.id == s_ext.id) {
isheriff6f8d6862016-05-26 11:24:55 -07003377 EXPECT_EQ(e_ext.uri, s_ext.uri);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003378 }
3379 }
3380 }
3381 }
3382
3383 // Disable receive extensions.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003384 channel_->SetRecvParameters(cricket::AudioRecvParameters());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003385 for (uint32_t ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003386 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003387 EXPECT_NE(nullptr, s);
3388 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3389 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003390}
3391
3392TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3393 // Test that packets are forwarded to the Call when configured accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003394 const uint32_t kAudioSsrc = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003395 rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003396 static const unsigned char kRtcp[] = {
3397 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3398 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3401 };
jbaucheec21bd2016-03-20 06:15:43 -07003402 rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003403
solenbergff976312016-03-30 23:28:51 -07003404 EXPECT_TRUE(SetupSendStream());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003405 cricket::WebRtcVoiceMediaChannel* media_channel =
3406 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
solenberg059fb442016-10-26 05:12:24 -07003407 SetSendParameters(send_parameters_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003408 EXPECT_TRUE(media_channel->AddRecvStream(
3409 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3410
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003411 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003412 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003413 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003414 EXPECT_EQ(0, s->received_packets());
3415 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3416 EXPECT_EQ(1, s->received_packets());
3417 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3418 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003419}
Minyue2013aec2015-05-13 14:14:42 +02003420
solenberg0a617e22015-10-20 15:49:38 -07003421// All receive channels should be associated with the first send channel,
solenberg1ac56142015-10-13 03:58:19 -07003422// since they do not send RTCP SR.
solenberg7602aab2016-11-14 11:30:07 -08003423TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_SendCreatedFirst) {
solenbergff976312016-03-30 23:28:51 -07003424 EXPECT_TRUE(SetupSendStream());
solenberg2100c0b2017-03-01 11:29:29 -08003425 EXPECT_TRUE(AddRecvStream(kSsrcY));
3426 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003427 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003428 cricket::StreamParams::CreateLegacy(kSsrcZ)));
3429 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcY).rtp.local_ssrc);
3430 EXPECT_TRUE(AddRecvStream(kSsrcW));
3431 EXPECT_EQ(kSsrcX, GetRecvStreamConfig(kSsrcW).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003432}
3433
solenberg7602aab2016-11-14 11:30:07 -08003434TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
3435 EXPECT_TRUE(SetupRecvStream());
solenberg2100c0b2017-03-01 11:29:29 -08003436 EXPECT_EQ(0xFA17FA17u, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003437 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003438 cricket::StreamParams::CreateLegacy(kSsrcY)));
3439 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3440 EXPECT_TRUE(AddRecvStream(kSsrcZ));
3441 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
solenberg7602aab2016-11-14 11:30:07 -08003442 EXPECT_TRUE(channel_->AddSendStream(
solenberg2100c0b2017-03-01 11:29:29 -08003443 cricket::StreamParams::CreateLegacy(kSsrcW)));
3444 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
3445 EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
Minyue2013aec2015-05-13 14:14:42 +02003446}
stefan658910c2015-09-03 05:48:32 -07003447
deadbeef884f5852016-01-15 09:20:04 -08003448TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
solenbergff976312016-03-30 23:28:51 -07003449 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003450 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3451 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003452
3453 // Setting the sink before a recv stream exists should do nothing.
solenberg2100c0b2017-03-01 11:29:29 -08003454 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_1));
3455 EXPECT_TRUE(AddRecvStream(kSsrcX));
3456 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003457
3458 // Now try actually setting the sink.
solenberg2100c0b2017-03-01 11:29:29 -08003459 channel_->SetRawAudioSink(kSsrcX, std::move(fake_sink_2));
3460 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003461
3462 // Now try resetting it.
solenberg2100c0b2017-03-01 11:29:29 -08003463 channel_->SetRawAudioSink(kSsrcX, nullptr);
3464 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
deadbeef884f5852016-01-15 09:20:04 -08003465}
3466
solenberg2100c0b2017-03-01 11:29:29 -08003467TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) {
solenbergff976312016-03-30 23:28:51 -07003468 EXPECT_TRUE(SetupChannel());
kwiberg686a8ef2016-02-26 03:00:35 -08003469 std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3470 std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
solenberg2100c0b2017-03-01 11:29:29 -08003471 std::unique_ptr<FakeAudioSink> fake_sink_3(new FakeAudioSink());
3472 std::unique_ptr<FakeAudioSink> fake_sink_4(new FakeAudioSink());
deadbeef884f5852016-01-15 09:20:04 -08003473
3474 // Should be able to set a default sink even when no stream exists.
3475 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3476
solenberg2100c0b2017-03-01 11:29:29 -08003477 // Spawn an unsignaled stream by sending a packet - it should be assigned the
3478 // default sink.
deadbeef884f5852016-01-15 09:20:04 -08003479 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003480 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003481
3482 // Try resetting the default sink.
solenberg2100c0b2017-03-01 11:29:29 -08003483 channel_->SetRawAudioSink(kSsrc0, nullptr);
3484 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003485
3486 // Try setting the default sink while the default stream exists.
solenberg2100c0b2017-03-01 11:29:29 -08003487 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2));
3488 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
deadbeef884f5852016-01-15 09:20:04 -08003489
3490 // If we remove and add a default stream, it should get the same sink.
solenberg2100c0b2017-03-01 11:29:29 -08003491 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
deadbeef884f5852016-01-15 09:20:04 -08003492 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
solenberg2100c0b2017-03-01 11:29:29 -08003493 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3494
3495 // Spawn another unsignaled stream - it should be assigned the default sink
3496 // and the previous unsignaled stream should lose it.
3497 unsigned char pcmuFrame2[sizeof(kPcmuFrame)];
3498 memcpy(pcmuFrame2, kPcmuFrame, sizeof(kPcmuFrame));
3499 rtc::SetBE32(&pcmuFrame2[8], kSsrcX);
3500 DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2));
solenbergebb349d2017-03-13 05:46:15 -07003501 if (kMaxUnsignaledRecvStreams > 1) {
3502 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3503 }
solenberg2100c0b2017-03-01 11:29:29 -08003504 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3505
3506 // Reset the default sink - the second unsignaled stream should lose it.
3507 channel_->SetRawAudioSink(kSsrc0, nullptr);
solenbergebb349d2017-03-13 05:46:15 -07003508 if (kMaxUnsignaledRecvStreams > 1) {
3509 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3510 }
solenberg2100c0b2017-03-01 11:29:29 -08003511 EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink());
3512
3513 // Try setting the default sink while two streams exists.
3514 channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3));
solenbergebb349d2017-03-13 05:46:15 -07003515 if (kMaxUnsignaledRecvStreams > 1) {
3516 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3517 }
solenberg2100c0b2017-03-01 11:29:29 -08003518 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
3519
3520 // Try setting the sink for the first unsignaled stream using its known SSRC.
3521 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_4));
solenbergebb349d2017-03-13 05:46:15 -07003522 if (kMaxUnsignaledRecvStreams > 1) {
3523 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3524 }
solenberg2100c0b2017-03-01 11:29:29 -08003525 EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink());
solenbergebb349d2017-03-13 05:46:15 -07003526 if (kMaxUnsignaledRecvStreams > 1) {
3527 EXPECT_NE(GetRecvStream(kSsrc1).sink(), GetRecvStream(kSsrcX).sink());
3528 }
deadbeef884f5852016-01-15 09:20:04 -08003529}
3530
skvlad7a43d252016-03-22 15:32:27 -07003531// Test that, just like the video channel, the voice channel communicates the
3532// network state to the call.
3533TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
solenbergff976312016-03-30 23:28:51 -07003534 EXPECT_TRUE(SetupChannel());
skvlad7a43d252016-03-22 15:32:27 -07003535
3536 EXPECT_EQ(webrtc::kNetworkUp,
3537 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3538 EXPECT_EQ(webrtc::kNetworkUp,
3539 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3540
3541 channel_->OnReadyToSend(false);
3542 EXPECT_EQ(webrtc::kNetworkDown,
3543 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3544 EXPECT_EQ(webrtc::kNetworkUp,
3545 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3546
3547 channel_->OnReadyToSend(true);
3548 EXPECT_EQ(webrtc::kNetworkUp,
3549 call_.GetNetworkState(webrtc::MediaType::AUDIO));
3550 EXPECT_EQ(webrtc::kNetworkUp,
3551 call_.GetNetworkState(webrtc::MediaType::VIDEO));
3552}
3553
aleloi18e0b672016-10-04 02:45:47 -07003554// Test that playout is still started after changing parameters
3555TEST_F(WebRtcVoiceEngineTestFake, PreservePlayoutWhenRecreateRecvStream) {
3556 SetupRecvStream();
3557 channel_->SetPlayout(true);
solenberg2100c0b2017-03-01 11:29:29 -08003558 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003559
3560 // Changing RTP header extensions will recreate the AudioReceiveStream.
3561 cricket::AudioRecvParameters parameters;
3562 parameters.extensions.push_back(
3563 webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, 12));
3564 channel_->SetRecvParameters(parameters);
3565
solenberg2100c0b2017-03-01 11:29:29 -08003566 EXPECT_TRUE(GetRecvStream(kSsrcX).started());
aleloi18e0b672016-10-04 02:45:47 -07003567}
3568
stefan658910c2015-09-03 05:48:32 -07003569// Tests that the library initializes and shuts down properly.
3570TEST(WebRtcVoiceEngineTest, StartupShutdown) {
ossu29b1a8d2016-06-13 07:34:51 -07003571 // If the VoiceEngine wants to gather available codecs early, that's fine but
3572 // we never want it to create a decoder at this stage.
ossuc54071d2016-08-17 02:45:41 -07003573 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003574 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003575 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003576 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003577 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003578 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3579 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003580 EXPECT_TRUE(channel != nullptr);
3581 delete channel;
solenbergff976312016-03-30 23:28:51 -07003582}
stefan658910c2015-09-03 05:48:32 -07003583
solenbergff976312016-03-30 23:28:51 -07003584// Tests that reference counting on the external ADM is correct.
solenbergbc37fc82016-04-04 09:54:44 -07003585TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
3586 testing::NiceMock<webrtc::test::MockAudioDeviceModule> adm;
3587 EXPECT_CALL(adm, AddRef()).Times(3).WillRepeatedly(Return(0));
3588 EXPECT_CALL(adm, Release()).Times(3).WillRepeatedly(Return(0));
tommi322a9e42017-02-28 02:12:57 -08003589 // Return 100ms just in case this function gets called. If we don't,
3590 // we could enter a tight loop since the mock would return 0.
3591 EXPECT_CALL(adm, TimeUntilNextProcess()).WillRepeatedly(Return(100));
solenbergff976312016-03-30 23:28:51 -07003592 {
ossuc54071d2016-08-17 02:45:41 -07003593 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003594 &adm, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003595 webrtc::RtcEventLogNullImpl event_log;
solenbergff976312016-03-30 23:28:51 -07003596 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003597 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
solenbergff976312016-03-30 23:28:51 -07003598 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3599 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
3600 EXPECT_TRUE(channel != nullptr);
3601 delete channel;
3602 }
stefan658910c2015-09-03 05:48:32 -07003603}
3604
3605// Tests that the library is configured with the codecs we want.
3606TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003607 // TODO(ossu): These tests should move into a future "builtin audio codecs"
3608 // module.
3609
stefan658910c2015-09-03 05:48:32 -07003610 // Check codecs by name.
ossu11bfc532017-02-16 05:37:06 -08003611#ifdef WEBRTC_CODEC_OPUS
solenberg26c8c912015-11-27 04:00:25 -08003612 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003613 cricket::AudioCodec(96, "OPUS", 48000, 0, 2), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003614#endif
3615#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
solenberg26c8c912015-11-27 04:00:25 -08003616 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003617 cricket::AudioCodec(96, "ISAC", 16000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003618#endif
3619#if (defined(WEBRTC_CODEC_ISAC))
solenberg26c8c912015-11-27 04:00:25 -08003620 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003621 cricket::AudioCodec(96, "ISAC", 32000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003622#endif
3623#ifdef WEBRTC_CODEC_ILBC
stefan658910c2015-09-03 05:48:32 -07003624 // Check that name matching is case-insensitive.
solenberg26c8c912015-11-27 04:00:25 -08003625 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003626 cricket::AudioCodec(96, "ILBC", 8000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003627 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003628 cricket::AudioCodec(96, "iLBC", 8000, 0, 1), nullptr));
ossu11bfc532017-02-16 05:37:06 -08003629#endif
solenberg26c8c912015-11-27 04:00:25 -08003630 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003631 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003632 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003633 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003634 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003635 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr));
solenberg2779bab2016-11-17 04:45:19 -08003636 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3637 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr));
3638 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3639 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr));
3640 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3641 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003642 // Check codecs with an id by id.
solenberg26c8c912015-11-27 04:00:25 -08003643 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003644 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU
solenberg26c8c912015-11-27 04:00:25 -08003645 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003646 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA
solenberg26c8c912015-11-27 04:00:25 -08003647 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003648 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722
solenberg26c8c912015-11-27 04:00:25 -08003649 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003650 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN
stefan658910c2015-09-03 05:48:32 -07003651 // Check sample/bitrate matching.
solenberg26c8c912015-11-27 04:00:25 -08003652 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003653 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr));
stefan658910c2015-09-03 05:48:32 -07003654 // Check that bad codecs fail.
solenberg26c8c912015-11-27 04:00:25 -08003655 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003656 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003657 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003658 cricket::AudioCodec(88, "", 0, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003659 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003660 cricket::AudioCodec(0, "", 0, 0, 2), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003661 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003662 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003663 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
deadbeef67cf2c12016-04-13 10:07:16 -07003664 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr));
solenberg26c8c912015-11-27 04:00:25 -08003665
stefan658910c2015-09-03 05:48:32 -07003666 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
ossuc54071d2016-08-17 02:45:41 -07003667 // TODO(ossu): Why are the payload types of codecs with non-static payload
3668 // type assignments checked here? It shouldn't really matter.
3669 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003670 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
solenberg2779bab2016-11-17 04:45:19 -08003671 for (const cricket::AudioCodec& codec : engine.send_codecs()) {
3672 if (codec.name == "CN" && codec.clockrate == 16000) {
3673 EXPECT_EQ(105, codec.id);
3674 } else if (codec.name == "CN" && codec.clockrate == 32000) {
3675 EXPECT_EQ(106, codec.id);
3676 } else if (codec.name == "ISAC" && codec.clockrate == 16000) {
3677 EXPECT_EQ(103, codec.id);
3678 } else if (codec.name == "ISAC" && codec.clockrate == 32000) {
3679 EXPECT_EQ(104, codec.id);
3680 } else if (codec.name == "G722" && codec.clockrate == 8000) {
3681 EXPECT_EQ(9, codec.id);
3682 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) {
3683 EXPECT_EQ(126, codec.id);
3684 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned.
3685 // Remove these checks once both send and receive side assigns payload types
3686 // dynamically.
3687 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) {
3688 EXPECT_EQ(113, codec.id);
3689 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) {
3690 EXPECT_EQ(112, codec.id);
3691 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) {
3692 EXPECT_EQ(110, codec.id);
3693 } else if (codec.name == "opus") {
3694 EXPECT_EQ(111, codec.id);
3695 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end());
3696 EXPECT_EQ("10", codec.params.find("minptime")->second);
3697 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end());
3698 EXPECT_EQ("1", codec.params.find("useinbandfec")->second);
stefan658910c2015-09-03 05:48:32 -07003699 }
3700 }
stefan658910c2015-09-03 05:48:32 -07003701}
3702
3703// Tests that VoE supports at least 32 channels
3704TEST(WebRtcVoiceEngineTest, Has32Channels) {
ossuc54071d2016-08-17 02:45:41 -07003705 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003706 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003707 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003708 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003709 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
stefan658910c2015-09-03 05:48:32 -07003710
3711 cricket::VoiceMediaChannel* channels[32];
3712 int num_channels = 0;
tfarina5237aaf2015-11-10 23:44:30 -08003713 while (num_channels < arraysize(channels)) {
nisse51542be2016-02-12 02:27:06 -08003714 cricket::VoiceMediaChannel* channel = engine.CreateChannel(
3715 call.get(), cricket::MediaConfig(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003716 if (!channel)
3717 break;
stefan658910c2015-09-03 05:48:32 -07003718 channels[num_channels++] = channel;
3719 }
3720
tfarina5237aaf2015-11-10 23:44:30 -08003721 int expected = arraysize(channels);
stefan658910c2015-09-03 05:48:32 -07003722 EXPECT_EQ(expected, num_channels);
3723
3724 while (num_channels > 0) {
3725 delete channels[--num_channels];
3726 }
stefan658910c2015-09-03 05:48:32 -07003727}
3728
3729// Test that we set our preferred codecs properly.
3730TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
ossu29b1a8d2016-06-13 07:34:51 -07003731 // TODO(ossu): I'm not sure of the intent of this test. It's either:
3732 // - Check that our builtin codecs are usable by Channel.
3733 // - The codecs provided by the engine is usable by Channel.
3734 // It does not check that the codecs in the RecvParameters are actually
3735 // what we sent in - though it's probably reasonable to expect so, if
3736 // SetRecvParameters returns true.
3737 // I think it will become clear once audio decoder injection is completed.
3738 cricket::WebRtcVoiceEngine engine(
gyzhou95aa9642016-12-13 14:06:26 -08003739 nullptr, webrtc::CreateBuiltinAudioDecoderFactory(), nullptr);
skvlad11a9cbf2016-10-07 11:53:05 -07003740 webrtc::RtcEventLogNullImpl event_log;
kwiberg686a8ef2016-02-26 03:00:35 -08003741 std::unique_ptr<webrtc::Call> call(
skvlad11a9cbf2016-10-07 11:53:05 -07003742 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
nisse51542be2016-02-12 02:27:06 -08003743 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
3744 cricket::AudioOptions(), call.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003745 cricket::AudioRecvParameters parameters;
ossudedfd282016-06-14 07:12:39 -07003746 parameters.codecs = engine.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003747 EXPECT_TRUE(channel.SetRecvParameters(parameters));
stefan658910c2015-09-03 05:48:32 -07003748}
ossu9def8002017-02-09 05:14:32 -08003749
3750TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) {
3751 std::vector<webrtc::AudioCodecSpec> specs;
3752 webrtc::AudioCodecSpec spec1({"codec1", 48000, 2, {{"param1", "value1"}}});
3753 spec1.allow_comfort_noise = false;
3754 spec1.supports_network_adaption = true;
3755 specs.push_back(spec1);
3756 webrtc::AudioCodecSpec spec2({"codec2", 32000, 1});
3757 spec2.allow_comfort_noise = false;
3758 specs.push_back(spec2);
3759 specs.push_back(webrtc::AudioCodecSpec({"codec3", 16000, 1,
3760 {{"param1", "value1b"},
3761 {"param2", "value2"}}}));
3762 specs.push_back(webrtc::AudioCodecSpec({"codec4", 8000, 1}));
3763 specs.push_back(webrtc::AudioCodecSpec({"codec5", 8000, 2}));
3764
3765 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_factory =
3766 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>;
3767 EXPECT_CALL(*mock_factory.get(), GetSupportedDecoders())
3768 .WillOnce(Return(specs));
3769
3770 cricket::WebRtcVoiceEngine engine(nullptr, mock_factory, nullptr);
3771 auto codecs = engine.recv_codecs();
3772 EXPECT_EQ(11, codecs.size());
3773
3774 // Rather than just ASSERTing that there are enough codecs, ensure that we can
3775 // check the actual values safely, to provide better test results.
3776 auto get_codec =
3777 [&codecs](size_t index) -> const cricket::AudioCodec& {
3778 static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
3779 if (codecs.size() > index)
3780 return codecs[index];
3781 return missing_codec;
3782 };
3783
3784 // Ensure the general codecs are generated first and in order.
3785 for (size_t i = 0; i != specs.size(); ++i) {
3786 EXPECT_EQ(specs[i].format.name, get_codec(i).name);
3787 EXPECT_EQ(specs[i].format.clockrate_hz, get_codec(i).clockrate);
3788 EXPECT_EQ(specs[i].format.num_channels, get_codec(i).channels);
3789 EXPECT_EQ(specs[i].format.parameters, get_codec(i).params);
3790 }
3791
3792 // Find the index of a codec, or -1 if not found, so that we can easily check
ossubcd88db2017-02-13 07:04:05 -08003793 // supplementary codecs are ordered after the general codecs.
ossu9def8002017-02-09 05:14:32 -08003794 auto find_codec =
3795 [&codecs](const webrtc::SdpAudioFormat& format) -> int {
3796 for (size_t i = 0; i != codecs.size(); ++i) {
3797 const cricket::AudioCodec& codec = codecs[i];
3798 if (STR_CASE_CMP(codec.name.c_str(), format.name.c_str()) == 0 &&
3799 codec.clockrate == format.clockrate_hz &&
3800 codec.channels == format.num_channels) {
ossubcd88db2017-02-13 07:04:05 -08003801 return rtc::checked_cast<int>(i);
ossu9def8002017-02-09 05:14:32 -08003802 }
3803 }
3804 return -1;
3805 };
3806
3807 // Ensure all supplementary codecs are generated last. Their internal ordering
3808 // is not important.
3809 // Without this cast, the comparison turned unsigned and, thus, failed for -1.
3810 const int num_specs = static_cast<int>(specs.size());
3811 EXPECT_GE(find_codec({"cn", 8000, 1}), num_specs);
3812 EXPECT_GE(find_codec({"cn", 16000, 1}), num_specs);
3813 EXPECT_EQ(find_codec({"cn", 32000, 1}), -1);
3814 EXPECT_GE(find_codec({"telephone-event", 8000, 1}), num_specs);
3815 EXPECT_GE(find_codec({"telephone-event", 16000, 1}), num_specs);
3816 EXPECT_GE(find_codec({"telephone-event", 32000, 1}), num_specs);
3817 EXPECT_GE(find_codec({"telephone-event", 48000, 1}), num_specs);
3818}