1 /*
2 * libjingle
3 * Copyright 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "webrtc/base/arraysize.h"
29 #include "webrtc/base/byteorder.h"
30 #include "webrtc/base/gunit.h"
31 #include "webrtc/call.h"
32 #include "talk/media/base/constants.h"
33 #include "talk/media/base/fakemediaengine.h"
34 #include "talk/media/base/fakenetworkinterface.h"
35 #include "talk/media/base/fakertp.h"
36 #include "talk/media/webrtc/fakewebrtccall.h"
37 #include "talk/media/webrtc/fakewebrtcvoiceengine.h"
38 #include "talk/media/webrtc/webrtcvoiceengine.h"
39 #include "webrtc/p2p/base/faketransportcontroller.h"
40 #include "talk/session/media/channel.h"
41
42 using cricket::kRtpAudioLevelHeaderExtension;
43 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
44
45 namespace {
46
47 const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48 const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
49 const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
50 const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
51 const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
52 const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
53 const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
54 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
55 const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0,
56 1, 0);
57 const uint32_t kSsrc1 = 0x99;
58 const uint32_t kSsrc2 = 0x98;
59 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
60
61 class FakeVoEWrapper : public cricket::VoEWrapper {
62 public:
FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine * engine)63 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
64 : cricket::VoEWrapper(engine, // processing
65 engine, // base
66 engine, // codec
67 engine, // hw
68 engine, // network
69 engine, // rtp
70 engine) { // volume
71 }
72 };
73 } // namespace
74
75 class WebRtcVoiceEngineTestFake : public testing::Test {
76 public:
WebRtcVoiceEngineTestFake()77 WebRtcVoiceEngineTestFake()
78 : call_(webrtc::Call::Config()),
79 engine_(new FakeVoEWrapper(&voe_)),
80 channel_(nullptr) {
81 send_parameters_.codecs.push_back(kPcmuCodec);
82 recv_parameters_.codecs.push_back(kPcmuCodec);
83 }
SetupEngine()84 bool SetupEngine() {
85 if (!engine_.Init(rtc::Thread::Current())) {
86 return false;
87 }
88 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
89 return (channel_ != nullptr);
90 }
SetupEngineWithRecvStream()91 bool SetupEngineWithRecvStream() {
92 if (!SetupEngine()) {
93 return false;
94 }
95 return channel_->AddRecvStream(
96 cricket::StreamParams::CreateLegacy(kSsrc1));
97 }
SetupEngineWithSendStream()98 bool SetupEngineWithSendStream() {
99 if (!SetupEngine()) {
100 return false;
101 }
102 return channel_->AddSendStream(
103 cricket::StreamParams::CreateLegacy(kSsrc1));
104 }
SetupForMultiSendStream()105 void SetupForMultiSendStream() {
106 EXPECT_TRUE(SetupEngineWithSendStream());
107 // Remove stream added in Setup.
108 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
109 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
110 // Verify the channel does not exist.
111 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
112 }
DeliverPacket(const void * data,int len)113 void DeliverPacket(const void* data, int len) {
114 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
115 channel_->OnPacketReceived(&packet, rtc::PacketTime());
116 }
TearDown()117 void TearDown() override {
118 delete channel_;
119 engine_.Terminate();
120 }
121
GetSendStream(uint32_t ssrc)122 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
123 const auto* send_stream = call_.GetAudioSendStream(ssrc);
124 EXPECT_TRUE(send_stream);
125 return *send_stream;
126 }
127
GetSendStreamConfig(uint32_t ssrc)128 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
129 const auto* send_stream = call_.GetAudioSendStream(ssrc);
130 EXPECT_TRUE(send_stream);
131 return send_stream->GetConfig();
132 }
133
GetRecvStreamConfig(uint32_t ssrc)134 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
135 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
136 EXPECT_TRUE(recv_stream);
137 return recv_stream->GetConfig();
138 }
139
TestInsertDtmf(uint32_t ssrc,bool caller)140 void TestInsertDtmf(uint32_t ssrc, bool caller) {
141 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
142 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
143 EXPECT_TRUE(channel_ != nullptr);
144 if (caller) {
145 // If this is a caller, local description will be applied and add the
146 // send stream.
147 EXPECT_TRUE(channel_->AddSendStream(
148 cricket::StreamParams::CreateLegacy(kSsrc1)));
149 }
150
151 // Test we can only InsertDtmf when the other side supports telephone-event.
152 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
153 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
154 EXPECT_FALSE(channel_->CanInsertDtmf());
155 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
156 send_parameters_.codecs.push_back(kTelephoneEventCodec);
157 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
158 EXPECT_TRUE(channel_->CanInsertDtmf());
159
160 if (!caller) {
161 // If this is callee, there's no active send channel yet.
162 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
163 EXPECT_TRUE(channel_->AddSendStream(
164 cricket::StreamParams::CreateLegacy(kSsrc1)));
165 }
166
167 // Check we fail if the ssrc is invalid.
168 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
169
170 // Test send.
171 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
172 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
173 EXPECT_EQ(-1, telephone_event.payload_type);
174 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
175 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
176 EXPECT_EQ(kTelephoneEventCodec.id, telephone_event.payload_type);
177 EXPECT_EQ(2, telephone_event.event_code);
178 EXPECT_EQ(123, telephone_event.duration_ms);
179 }
180
181 // Test that send bandwidth is set correctly.
182 // |codec| is the codec under test.
183 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
184 // |expected_result| is the expected result from SetMaxSendBandwidth().
185 // |expected_bitrate| is the expected audio bitrate afterward.
TestSendBandwidth(const cricket::AudioCodec & codec,int max_bitrate,bool expected_result,int expected_bitrate)186 void TestSendBandwidth(const cricket::AudioCodec& codec,
187 int max_bitrate,
188 bool expected_result,
189 int expected_bitrate) {
190 cricket::AudioSendParameters parameters;
191 parameters.codecs.push_back(codec);
192 parameters.max_bandwidth_bps = max_bitrate;
193 EXPECT_EQ(expected_result, channel_->SetSendParameters(parameters));
194
195 int channel_num = voe_.GetLastChannel();
196 webrtc::CodecInst temp_codec;
197 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
198 EXPECT_EQ(expected_bitrate, temp_codec.rate);
199 }
200
TestSetSendRtpHeaderExtensions(const std::string & ext)201 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
202 EXPECT_TRUE(SetupEngineWithSendStream());
203
204 // Ensure extensions are off by default.
205 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
206
207 // Ensure unknown extensions won't cause an error.
208 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
209 "urn:ietf:params:unknownextention", 1));
210 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
211 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
212
213 // Ensure extensions stay off with an empty list of headers.
214 send_parameters_.extensions.clear();
215 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
216 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
217
218 // Ensure extension is set properly.
219 const int id = 1;
220 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
221 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
222 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
223 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].name);
224 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
225
226 // Ensure extension is set properly on new stream.
227 EXPECT_TRUE(channel_->AddSendStream(
228 cricket::StreamParams::CreateLegacy(kSsrc2)));
229 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
230 call_.GetAudioSendStream(kSsrc2));
231 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
232 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].name);
233 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
234
235 // Ensure all extensions go back off with an empty list.
236 send_parameters_.codecs.push_back(kPcmuCodec);
237 send_parameters_.extensions.clear();
238 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
239 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
240 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
241 }
242
TestSetRecvRtpHeaderExtensions(const std::string & ext)243 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
244 EXPECT_TRUE(SetupEngineWithRecvStream());
245
246 // Ensure extensions are off by default.
247 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
248
249 // Ensure unknown extensions won't cause an error.
250 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
251 "urn:ietf:params:unknownextention", 1));
252 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
253 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
254
255 // Ensure extensions stay off with an empty list of headers.
256 recv_parameters_.extensions.clear();
257 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
258 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
259
260 // Ensure extension is set properly.
261 const int id = 2;
262 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
263 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
264 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
265 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].name);
266 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
267
268 // Ensure extension is set properly on new stream.
269 EXPECT_TRUE(channel_->AddRecvStream(
270 cricket::StreamParams::CreateLegacy(kSsrc2)));
271 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
272 call_.GetAudioReceiveStream(kSsrc2));
273 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
274 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].name);
275 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
276
277 // Ensure all extensions go back off with an empty list.
278 recv_parameters_.extensions.clear();
279 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
280 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
281 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
282 }
283
GetAudioSendStreamStats() const284 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
285 webrtc::AudioSendStream::Stats stats;
286 stats.local_ssrc = 12;
287 stats.bytes_sent = 345;
288 stats.packets_sent = 678;
289 stats.packets_lost = 9012;
290 stats.fraction_lost = 34.56f;
291 stats.codec_name = "codec_name_send";
292 stats.ext_seqnum = 789;
293 stats.jitter_ms = 12;
294 stats.rtt_ms = 345;
295 stats.audio_level = 678;
296 stats.aec_quality_min = 9.01f;
297 stats.echo_delay_median_ms = 234;
298 stats.echo_delay_std_ms = 567;
299 stats.echo_return_loss = 890;
300 stats.echo_return_loss_enhancement = 1234;
301 stats.typing_noise_detected = true;
302 return stats;
303 }
SetAudioSendStreamStats()304 void SetAudioSendStreamStats() {
305 for (auto* s : call_.GetAudioSendStreams()) {
306 s->SetStats(GetAudioSendStreamStats());
307 }
308 }
VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo & info,bool is_sending)309 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
310 bool is_sending) {
311 const auto stats = GetAudioSendStreamStats();
312 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
313 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
314 EXPECT_EQ(info.packets_sent, stats.packets_sent);
315 EXPECT_EQ(info.packets_lost, stats.packets_lost);
316 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
317 EXPECT_EQ(info.codec_name, stats.codec_name);
318 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
319 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
320 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
321 EXPECT_EQ(info.audio_level, stats.audio_level);
322 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
323 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
324 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
325 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
326 EXPECT_EQ(info.echo_return_loss_enhancement,
327 stats.echo_return_loss_enhancement);
328 EXPECT_EQ(info.typing_noise_detected,
329 stats.typing_noise_detected && is_sending);
330 }
331
GetAudioReceiveStreamStats() const332 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
333 webrtc::AudioReceiveStream::Stats stats;
334 stats.remote_ssrc = 123;
335 stats.bytes_rcvd = 456;
336 stats.packets_rcvd = 768;
337 stats.packets_lost = 101;
338 stats.fraction_lost = 23.45f;
339 stats.codec_name = "codec_name_recv";
340 stats.ext_seqnum = 678;
341 stats.jitter_ms = 901;
342 stats.jitter_buffer_ms = 234;
343 stats.jitter_buffer_preferred_ms = 567;
344 stats.delay_estimate_ms = 890;
345 stats.audio_level = 1234;
346 stats.expand_rate = 5.67f;
347 stats.speech_expand_rate = 8.90f;
348 stats.secondary_decoded_rate = 1.23f;
349 stats.accelerate_rate = 4.56f;
350 stats.preemptive_expand_rate = 7.89f;
351 stats.decoding_calls_to_silence_generator = 12;
352 stats.decoding_calls_to_neteq = 345;
353 stats.decoding_normal = 67890;
354 stats.decoding_plc = 1234;
355 stats.decoding_cng = 5678;
356 stats.decoding_plc_cng = 9012;
357 stats.capture_start_ntp_time_ms = 3456;
358 return stats;
359 }
SetAudioReceiveStreamStats()360 void SetAudioReceiveStreamStats() {
361 for (auto* s : call_.GetAudioReceiveStreams()) {
362 s->SetStats(GetAudioReceiveStreamStats());
363 }
364 }
VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo & info)365 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
366 const auto stats = GetAudioReceiveStreamStats();
367 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
368 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
369 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
370 EXPECT_EQ(info.packets_lost, stats.packets_lost);
371 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
372 EXPECT_EQ(info.codec_name, stats.codec_name);
373 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
374 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
375 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
376 EXPECT_EQ(info.jitter_buffer_preferred_ms,
377 stats.jitter_buffer_preferred_ms);
378 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
379 EXPECT_EQ(info.audio_level, stats.audio_level);
380 EXPECT_EQ(info.expand_rate, stats.expand_rate);
381 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
382 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
383 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
384 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
385 EXPECT_EQ(info.decoding_calls_to_silence_generator,
386 stats.decoding_calls_to_silence_generator);
387 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
388 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
389 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
390 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
391 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
392 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
393 }
394
395 protected:
396 cricket::FakeCall call_;
397 cricket::FakeWebRtcVoiceEngine voe_;
398 cricket::WebRtcVoiceEngine engine_;
399 cricket::VoiceMediaChannel* channel_;
400 cricket::AudioSendParameters send_parameters_;
401 cricket::AudioRecvParameters recv_parameters_;
402 };
403
404 // Tests that our stub library "works".
TEST_F(WebRtcVoiceEngineTestFake,StartupShutdown)405 TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
406 EXPECT_FALSE(voe_.IsInited());
407 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
408 EXPECT_TRUE(voe_.IsInited());
409 engine_.Terminate();
410 EXPECT_FALSE(voe_.IsInited());
411 }
412
413 // Tests that we can create and destroy a channel.
TEST_F(WebRtcVoiceEngineTestFake,CreateChannel)414 TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
415 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
416 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
417 EXPECT_TRUE(channel_ != nullptr);
418 }
419
420 // Tests that the list of supported codecs is created properly and ordered
421 // correctly
TEST_F(WebRtcVoiceEngineTestFake,CodecPreference)422 TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
423 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
424 ASSERT_FALSE(codecs.empty());
425 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
426 EXPECT_EQ(48000, codecs[0].clockrate);
427 EXPECT_EQ(2, codecs[0].channels);
428 EXPECT_EQ(64000, codecs[0].bitrate);
429 int pref = codecs[0].preference;
430 for (size_t i = 1; i < codecs.size(); ++i) {
431 EXPECT_GT(pref, codecs[i].preference);
432 pref = codecs[i].preference;
433 }
434 }
435
436 // Tests that we can find codecs by name or id, and that we interpret the
437 // clockrate and bitrate fields properly.
TEST_F(WebRtcVoiceEngineTestFake,FindCodec)438 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
439 cricket::AudioCodec codec;
440 webrtc::CodecInst codec_inst;
441 // Find PCMU with explicit clockrate and bitrate.
442 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
443 // Find ISAC with explicit clockrate and 0 bitrate.
444 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
445 // Find telephone-event with explicit clockrate and 0 bitrate.
446 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec,
447 &codec_inst));
448 // Find ISAC with a different payload id.
449 codec = kIsacCodec;
450 codec.id = 127;
451 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
452 EXPECT_EQ(codec.id, codec_inst.pltype);
453 // Find PCMU with a 0 clockrate.
454 codec = kPcmuCodec;
455 codec.clockrate = 0;
456 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
457 EXPECT_EQ(codec.id, codec_inst.pltype);
458 EXPECT_EQ(8000, codec_inst.plfreq);
459 // Find PCMU with a 0 bitrate.
460 codec = kPcmuCodec;
461 codec.bitrate = 0;
462 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
463 EXPECT_EQ(codec.id, codec_inst.pltype);
464 EXPECT_EQ(64000, codec_inst.rate);
465 // Find ISAC with an explicit bitrate.
466 codec = kIsacCodec;
467 codec.bitrate = 32000;
468 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
469 EXPECT_EQ(codec.id, codec_inst.pltype);
470 EXPECT_EQ(32000, codec_inst.rate);
471 }
472
473 // Test that we set our inbound codecs properly, including changing PT.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecs)474 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
475 EXPECT_TRUE(SetupEngine());
476 cricket::AudioRecvParameters parameters;
477 parameters.codecs.push_back(kIsacCodec);
478 parameters.codecs.push_back(kPcmuCodec);
479 parameters.codecs.push_back(kTelephoneEventCodec);
480 parameters.codecs[0].id = 106; // collide with existing telephone-event
481 parameters.codecs[2].id = 126;
482 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
483 EXPECT_TRUE(channel_->AddRecvStream(
484 cricket::StreamParams::CreateLegacy(kSsrc1)));
485 int channel_num = voe_.GetLastChannel();
486 webrtc::CodecInst gcodec;
487 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
488 gcodec.plfreq = 16000;
489 gcodec.channels = 1;
490 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
491 EXPECT_EQ(106, gcodec.pltype);
492 EXPECT_STREQ("ISAC", gcodec.plname);
493 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
494 gcodec.plfreq = 8000;
495 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
496 EXPECT_EQ(126, gcodec.pltype);
497 EXPECT_STREQ("telephone-event", gcodec.plname);
498 }
499
500 // Test that we fail to set an unknown inbound codec.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsUnsupportedCodec)501 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
502 EXPECT_TRUE(SetupEngine());
503 cricket::AudioRecvParameters parameters;
504 parameters.codecs.push_back(kIsacCodec);
505 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
506 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
507 }
508
509 // Test that we fail if we have duplicate types in the inbound list.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsDuplicatePayloadType)510 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
511 EXPECT_TRUE(SetupEngine());
512 cricket::AudioRecvParameters parameters;
513 parameters.codecs.push_back(kIsacCodec);
514 parameters.codecs.push_back(kCn16000Codec);
515 parameters.codecs[1].id = kIsacCodec.id;
516 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
517 }
518
519 // Test that we can decode OPUS without stereo parameters.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpusNoStereo)520 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
521 EXPECT_TRUE(SetupEngine());
522 cricket::AudioRecvParameters parameters;
523 parameters.codecs.push_back(kIsacCodec);
524 parameters.codecs.push_back(kPcmuCodec);
525 parameters.codecs.push_back(kOpusCodec);
526 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
527 EXPECT_TRUE(channel_->AddRecvStream(
528 cricket::StreamParams::CreateLegacy(kSsrc1)));
529 int channel_num = voe_.GetLastChannel();
530 webrtc::CodecInst opus;
531 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
532 // Even without stereo parameters, recv codecs still specify channels = 2.
533 EXPECT_EQ(2, opus.channels);
534 EXPECT_EQ(111, opus.pltype);
535 EXPECT_STREQ("opus", opus.plname);
536 opus.pltype = 0;
537 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
538 EXPECT_EQ(111, opus.pltype);
539 }
540
541 // Test that we can decode OPUS with stereo = 0.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpus0Stereo)542 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
543 EXPECT_TRUE(SetupEngine());
544 cricket::AudioRecvParameters parameters;
545 parameters.codecs.push_back(kIsacCodec);
546 parameters.codecs.push_back(kPcmuCodec);
547 parameters.codecs.push_back(kOpusCodec);
548 parameters.codecs[2].params["stereo"] = "0";
549 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
550 EXPECT_TRUE(channel_->AddRecvStream(
551 cricket::StreamParams::CreateLegacy(kSsrc1)));
552 int channel_num2 = voe_.GetLastChannel();
553 webrtc::CodecInst opus;
554 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
555 // Even when stereo is off, recv codecs still specify channels = 2.
556 EXPECT_EQ(2, opus.channels);
557 EXPECT_EQ(111, opus.pltype);
558 EXPECT_STREQ("opus", opus.plname);
559 opus.pltype = 0;
560 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
561 EXPECT_EQ(111, opus.pltype);
562 }
563
564 // Test that we can decode OPUS with stereo = 1.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpus1Stereo)565 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
566 EXPECT_TRUE(SetupEngine());
567 cricket::AudioRecvParameters parameters;
568 parameters.codecs.push_back(kIsacCodec);
569 parameters.codecs.push_back(kPcmuCodec);
570 parameters.codecs.push_back(kOpusCodec);
571 parameters.codecs[2].params["stereo"] = "1";
572 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
573 EXPECT_TRUE(channel_->AddRecvStream(
574 cricket::StreamParams::CreateLegacy(kSsrc1)));
575 int channel_num2 = voe_.GetLastChannel();
576 webrtc::CodecInst opus;
577 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
578 EXPECT_EQ(2, opus.channels);
579 EXPECT_EQ(111, opus.pltype);
580 EXPECT_STREQ("opus", opus.plname);
581 opus.pltype = 0;
582 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
583 EXPECT_EQ(111, opus.pltype);
584 }
585
586 // Test that changes to recv codecs are applied to all streams.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithMultipleStreams)587 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
588 EXPECT_TRUE(SetupEngine());
589 cricket::AudioRecvParameters parameters;
590 parameters.codecs.push_back(kIsacCodec);
591 parameters.codecs.push_back(kPcmuCodec);
592 parameters.codecs.push_back(kTelephoneEventCodec);
593 parameters.codecs[0].id = 106; // collide with existing telephone-event
594 parameters.codecs[2].id = 126;
595 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
596 EXPECT_TRUE(channel_->AddRecvStream(
597 cricket::StreamParams::CreateLegacy(kSsrc1)));
598 int channel_num2 = voe_.GetLastChannel();
599 webrtc::CodecInst gcodec;
600 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
601 gcodec.plfreq = 16000;
602 gcodec.channels = 1;
603 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
604 EXPECT_EQ(106, gcodec.pltype);
605 EXPECT_STREQ("ISAC", gcodec.plname);
606 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
607 gcodec.plfreq = 8000;
608 gcodec.channels = 1;
609 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
610 EXPECT_EQ(126, gcodec.pltype);
611 EXPECT_STREQ("telephone-event", gcodec.plname);
612 }
613
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsAfterAddingStreams)614 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
615 EXPECT_TRUE(SetupEngineWithRecvStream());
616 cricket::AudioRecvParameters parameters;
617 parameters.codecs.push_back(kIsacCodec);
618 parameters.codecs[0].id = 106; // collide with existing telephone-event
619 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
620
621 int channel_num2 = voe_.GetLastChannel();
622 webrtc::CodecInst gcodec;
623 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
624 gcodec.plfreq = 16000;
625 gcodec.channels = 1;
626 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
627 EXPECT_EQ(106, gcodec.pltype);
628 EXPECT_STREQ("ISAC", gcodec.plname);
629 }
630
631 // Test that we can apply the same set of codecs again while playing.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWhilePlaying)632 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
633 EXPECT_TRUE(SetupEngineWithRecvStream());
634 cricket::AudioRecvParameters parameters;
635 parameters.codecs.push_back(kIsacCodec);
636 parameters.codecs.push_back(kCn16000Codec);
637 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
638 EXPECT_TRUE(channel_->SetPlayout(true));
639 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
640
641 // Changing the payload type of a codec should fail.
642 parameters.codecs[0].id = 127;
643 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
644 int channel_num = voe_.GetLastChannel();
645 EXPECT_TRUE(voe_.GetPlayout(channel_num));
646 }
647
648 // Test that we can add a codec while playing.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvCodecsWhilePlaying)649 TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
650 EXPECT_TRUE(SetupEngineWithRecvStream());
651 cricket::AudioRecvParameters parameters;
652 parameters.codecs.push_back(kIsacCodec);
653 parameters.codecs.push_back(kCn16000Codec);
654 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
655 EXPECT_TRUE(channel_->SetPlayout(true));
656
657 parameters.codecs.push_back(kOpusCodec);
658 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
659 int channel_num = voe_.GetLastChannel();
660 EXPECT_TRUE(voe_.GetPlayout(channel_num));
661 webrtc::CodecInst gcodec;
662 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
663 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
664 }
665
TEST_F(WebRtcVoiceEngineTestFake,SetSendBandwidthAuto)666 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
667 EXPECT_TRUE(SetupEngineWithSendStream());
668
669 // Test that when autobw is enabled, bitrate is kept as the default
670 // value. autobw is enabled for the following tests because the target
671 // bitrate is <= 0.
672
673 // ISAC, default bitrate == 32000.
674 TestSendBandwidth(kIsacCodec, 0, true, 32000);
675
676 // PCMU, default bitrate == 64000.
677 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
678
679 // opus, default bitrate == 64000.
680 TestSendBandwidth(kOpusCodec, -1, true, 64000);
681 }
682
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthMultiRateAsCaller)683 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
684 EXPECT_TRUE(SetupEngineWithSendStream());
685
686 // Test that the bitrate of a multi-rate codec is always the maximum.
687
688 // ISAC, default bitrate == 32000.
689 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
690 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
691
692 // opus, default bitrate == 64000.
693 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
694 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
695 }
696
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthFixedRateAsCaller)697 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
698 EXPECT_TRUE(SetupEngineWithSendStream());
699
700 // Test that we can only set a maximum bitrate for a fixed-rate codec
701 // if it's bigger than the fixed rate.
702
703 // PCMU, fixed bitrate == 64000.
704 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
705 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
706 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
707 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
708 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
709 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
710 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
711 }
712
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthMultiRateAsCallee)713 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
714 EXPECT_TRUE(SetupEngine());
715 const int kDesiredBitrate = 128000;
716 cricket::AudioSendParameters parameters;
717 parameters.codecs = engine_.codecs();
718 parameters.max_bandwidth_bps = kDesiredBitrate;
719 EXPECT_TRUE(channel_->SetSendParameters(parameters));
720
721 EXPECT_TRUE(channel_->AddSendStream(
722 cricket::StreamParams::CreateLegacy(kSsrc1)));
723
724 int channel_num = voe_.GetLastChannel();
725 webrtc::CodecInst codec;
726 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
727 EXPECT_EQ(kDesiredBitrate, codec.rate);
728 }
729
730 // Test that bitrate cannot be set for CBR codecs.
731 // Bitrate is ignored if it is higher than the fixed bitrate.
732 // Bitrate less then the fixed bitrate is an error.
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthCbr)733 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
734 EXPECT_TRUE(SetupEngineWithSendStream());
735
736 // PCMU, default bitrate == 64000.
737 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
738 int channel_num = voe_.GetLastChannel();
739 webrtc::CodecInst codec;
740 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
741 EXPECT_EQ(64000, codec.rate);
742
743 send_parameters_.max_bandwidth_bps = 128000;
744 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
745 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
746 EXPECT_EQ(64000, codec.rate);
747
748 send_parameters_.max_bandwidth_bps = 128;
749 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
750 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
751 EXPECT_EQ(64000, codec.rate);
752 }
753
754 // Test that we apply codecs properly.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecs)755 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
756 EXPECT_TRUE(SetupEngineWithSendStream());
757 cricket::AudioSendParameters parameters;
758 parameters.codecs.push_back(kIsacCodec);
759 parameters.codecs.push_back(kPcmuCodec);
760 parameters.codecs.push_back(kRedCodec);
761 parameters.codecs[0].id = 96;
762 parameters.codecs[0].bitrate = 48000;
763 EXPECT_TRUE(channel_->SetSendParameters(parameters));
764 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
765 int channel_num = voe_.GetLastChannel();
766 webrtc::CodecInst gcodec;
767 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
768 EXPECT_EQ(96, gcodec.pltype);
769 EXPECT_EQ(48000, gcodec.rate);
770 EXPECT_STREQ("ISAC", gcodec.plname);
771 EXPECT_FALSE(voe_.GetVAD(channel_num));
772 EXPECT_FALSE(voe_.GetRED(channel_num));
773 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
774 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
775 EXPECT_FALSE(channel_->CanInsertDtmf());
776 }
777
778 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
779 // to apply.
TEST_F(WebRtcVoiceEngineTestFake,DontResetSetSendCodec)780 TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
781 EXPECT_TRUE(SetupEngineWithSendStream());
782 cricket::AudioSendParameters parameters;
783 parameters.codecs.push_back(kIsacCodec);
784 parameters.codecs.push_back(kPcmuCodec);
785 parameters.codecs.push_back(kRedCodec);
786 parameters.codecs[0].id = 96;
787 parameters.codecs[0].bitrate = 48000;
788 EXPECT_TRUE(channel_->SetSendParameters(parameters));
789 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
790 // Calling SetSendCodec again with same codec which is already set.
791 // In this case media channel shouldn't send codec to VoE.
792 EXPECT_TRUE(channel_->SetSendParameters(parameters));
793 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
794 }
795
796 // Verify that G722 is set with 16000 samples per second to WebRTC.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecG722)797 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
798 EXPECT_TRUE(SetupEngineWithSendStream());
799 int channel_num = voe_.GetLastChannel();
800 cricket::AudioSendParameters parameters;
801 parameters.codecs.push_back(kG722CodecSdp);
802 EXPECT_TRUE(channel_->SetSendParameters(parameters));
803 webrtc::CodecInst gcodec;
804 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
805 EXPECT_STREQ("G722", gcodec.plname);
806 EXPECT_EQ(1, gcodec.channels);
807 EXPECT_EQ(16000, gcodec.plfreq);
808 }
809
810 // Test that if clockrate is not 48000 for opus, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBadClockrate)811 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
812 EXPECT_TRUE(SetupEngineWithSendStream());
813 cricket::AudioSendParameters parameters;
814 parameters.codecs.push_back(kOpusCodec);
815 parameters.codecs[0].bitrate = 0;
816 parameters.codecs[0].clockrate = 50000;
817 EXPECT_FALSE(channel_->SetSendParameters(parameters));
818 }
819
820 // Test that if channels=0 for opus, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad0ChannelsNoStereo)821 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
822 EXPECT_TRUE(SetupEngineWithSendStream());
823 cricket::AudioSendParameters parameters;
824 parameters.codecs.push_back(kOpusCodec);
825 parameters.codecs[0].bitrate = 0;
826 parameters.codecs[0].channels = 0;
827 EXPECT_FALSE(channel_->SetSendParameters(parameters));
828 }
829
830 // Test that if channels=0 for opus, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad0Channels1Stereo)831 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
832 EXPECT_TRUE(SetupEngineWithSendStream());
833 cricket::AudioSendParameters parameters;
834 parameters.codecs.push_back(kOpusCodec);
835 parameters.codecs[0].bitrate = 0;
836 parameters.codecs[0].channels = 0;
837 parameters.codecs[0].params["stereo"] = "1";
838 EXPECT_FALSE(channel_->SetSendParameters(parameters));
839 }
840
841 // Test that if channel is 1 for opus and there's no stereo, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpus1ChannelNoStereo)842 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
843 EXPECT_TRUE(SetupEngineWithSendStream());
844 cricket::AudioSendParameters parameters;
845 parameters.codecs.push_back(kOpusCodec);
846 parameters.codecs[0].bitrate = 0;
847 parameters.codecs[0].channels = 1;
848 EXPECT_FALSE(channel_->SetSendParameters(parameters));
849 }
850
851 // Test that if channel is 1 for opus and stereo=0, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad1Channel0Stereo)852 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
853 EXPECT_TRUE(SetupEngineWithSendStream());
854 cricket::AudioSendParameters parameters;
855 parameters.codecs.push_back(kOpusCodec);
856 parameters.codecs[0].bitrate = 0;
857 parameters.codecs[0].channels = 1;
858 parameters.codecs[0].params["stereo"] = "0";
859 EXPECT_FALSE(channel_->SetSendParameters(parameters));
860 }
861
862 // Test that if channel is 1 for opus and stereo=1, we fail.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad1Channel1Stereo)863 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
864 EXPECT_TRUE(SetupEngineWithSendStream());
865 cricket::AudioSendParameters parameters;
866 parameters.codecs.push_back(kOpusCodec);
867 parameters.codecs[0].bitrate = 0;
868 parameters.codecs[0].channels = 1;
869 parameters.codecs[0].params["stereo"] = "1";
870 EXPECT_FALSE(channel_->SetSendParameters(parameters));
871 }
872
873 // Test that with bitrate=0 and no stereo,
874 // channels and bitrate are 1 and 32000.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0BitrateNoStereo)875 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
876 EXPECT_TRUE(SetupEngineWithSendStream());
877 int channel_num = voe_.GetLastChannel();
878 cricket::AudioSendParameters parameters;
879 parameters.codecs.push_back(kOpusCodec);
880 parameters.codecs[0].bitrate = 0;
881 EXPECT_TRUE(channel_->SetSendParameters(parameters));
882 webrtc::CodecInst gcodec;
883 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
884 EXPECT_STREQ("opus", gcodec.plname);
885 EXPECT_EQ(1, gcodec.channels);
886 EXPECT_EQ(32000, gcodec.rate);
887 }
888
889 // Test that with bitrate=0 and stereo=0,
890 // channels and bitrate are 1 and 32000.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0Bitrate0Stereo)891 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
892 EXPECT_TRUE(SetupEngineWithSendStream());
893 int channel_num = voe_.GetLastChannel();
894 cricket::AudioSendParameters parameters;
895 parameters.codecs.push_back(kOpusCodec);
896 parameters.codecs[0].bitrate = 0;
897 parameters.codecs[0].params["stereo"] = "0";
898 EXPECT_TRUE(channel_->SetSendParameters(parameters));
899 webrtc::CodecInst gcodec;
900 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
901 EXPECT_STREQ("opus", gcodec.plname);
902 EXPECT_EQ(1, gcodec.channels);
903 EXPECT_EQ(32000, gcodec.rate);
904 }
905
906 // Test that with bitrate=invalid and stereo=0,
907 // channels and bitrate are 1 and 32000.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodXBitrate0Stereo)908 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
909 EXPECT_TRUE(SetupEngineWithSendStream());
910 int channel_num = voe_.GetLastChannel();
911 cricket::AudioSendParameters parameters;
912 parameters.codecs.push_back(kOpusCodec);
913 parameters.codecs[0].params["stereo"] = "0";
914 webrtc::CodecInst gcodec;
915
916 // bitrate that's out of the range between 6000 and 510000 will be clamped.
917 parameters.codecs[0].bitrate = 5999;
918 EXPECT_TRUE(channel_->SetSendParameters(parameters));
919 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
920 EXPECT_STREQ("opus", gcodec.plname);
921 EXPECT_EQ(1, gcodec.channels);
922 EXPECT_EQ(6000, gcodec.rate);
923
924 parameters.codecs[0].bitrate = 510001;
925 EXPECT_TRUE(channel_->SetSendParameters(parameters));
926 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
927 EXPECT_STREQ("opus", gcodec.plname);
928 EXPECT_EQ(1, gcodec.channels);
929 EXPECT_EQ(510000, gcodec.rate);
930 }
931
932 // Test that with bitrate=0 and stereo=1,
933 // channels and bitrate are 2 and 64000.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0Bitrate1Stereo)934 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
935 EXPECT_TRUE(SetupEngineWithSendStream());
936 int channel_num = voe_.GetLastChannel();
937 cricket::AudioSendParameters parameters;
938 parameters.codecs.push_back(kOpusCodec);
939 parameters.codecs[0].bitrate = 0;
940 parameters.codecs[0].params["stereo"] = "1";
941 EXPECT_TRUE(channel_->SetSendParameters(parameters));
942 webrtc::CodecInst gcodec;
943 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
944 EXPECT_STREQ("opus", gcodec.plname);
945 EXPECT_EQ(2, gcodec.channels);
946 EXPECT_EQ(64000, gcodec.rate);
947 }
948
949 // Test that with bitrate=invalid and stereo=1,
950 // channels and bitrate are 2 and 64000.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodXBitrate1Stereo)951 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
952 EXPECT_TRUE(SetupEngineWithSendStream());
953 int channel_num = voe_.GetLastChannel();
954 cricket::AudioSendParameters parameters;
955 parameters.codecs.push_back(kOpusCodec);
956 parameters.codecs[0].params["stereo"] = "1";
957 webrtc::CodecInst gcodec;
958
959 // bitrate that's out of the range between 6000 and 510000 will be clamped.
960 parameters.codecs[0].bitrate = 5999;
961 EXPECT_TRUE(channel_->SetSendParameters(parameters));
962 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
963 EXPECT_STREQ("opus", gcodec.plname);
964 EXPECT_EQ(2, gcodec.channels);
965 EXPECT_EQ(6000, gcodec.rate);
966
967 parameters.codecs[0].bitrate = 510001;
968 EXPECT_TRUE(channel_->SetSendParameters(parameters));
969 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
970 EXPECT_STREQ("opus", gcodec.plname);
971 EXPECT_EQ(2, gcodec.channels);
972 EXPECT_EQ(510000, gcodec.rate);
973 }
974
975 // Test that with bitrate=N and stereo unset,
976 // channels and bitrate are 1 and N.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrateNoStereo)977 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
978 EXPECT_TRUE(SetupEngineWithSendStream());
979 int channel_num = voe_.GetLastChannel();
980 cricket::AudioSendParameters parameters;
981 parameters.codecs.push_back(kOpusCodec);
982 parameters.codecs[0].bitrate = 96000;
983 EXPECT_TRUE(channel_->SetSendParameters(parameters));
984 webrtc::CodecInst gcodec;
985 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
986 EXPECT_EQ(111, gcodec.pltype);
987 EXPECT_EQ(96000, gcodec.rate);
988 EXPECT_STREQ("opus", gcodec.plname);
989 EXPECT_EQ(1, gcodec.channels);
990 EXPECT_EQ(48000, gcodec.plfreq);
991 }
992
993 // Test that with bitrate=N and stereo=0,
994 // channels and bitrate are 1 and N.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrate0Stereo)995 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
996 EXPECT_TRUE(SetupEngineWithSendStream());
997 int channel_num = voe_.GetLastChannel();
998 cricket::AudioSendParameters parameters;
999 parameters.codecs.push_back(kOpusCodec);
1000 parameters.codecs[0].bitrate = 30000;
1001 parameters.codecs[0].params["stereo"] = "0";
1002 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1003 webrtc::CodecInst gcodec;
1004 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1005 EXPECT_EQ(1, gcodec.channels);
1006 EXPECT_EQ(30000, gcodec.rate);
1007 EXPECT_STREQ("opus", gcodec.plname);
1008 }
1009
1010 // Test that with bitrate=N and without any parameters,
1011 // channels and bitrate are 1 and N.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrateNoParameters)1012 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
1013 EXPECT_TRUE(SetupEngineWithSendStream());
1014 int channel_num = voe_.GetLastChannel();
1015 cricket::AudioSendParameters parameters;
1016 parameters.codecs.push_back(kOpusCodec);
1017 parameters.codecs[0].bitrate = 30000;
1018 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1019 webrtc::CodecInst gcodec;
1020 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1021 EXPECT_EQ(1, gcodec.channels);
1022 EXPECT_EQ(30000, gcodec.rate);
1023 EXPECT_STREQ("opus", gcodec.plname);
1024 }
1025
1026 // Test that with bitrate=N and stereo=1,
1027 // channels and bitrate are 2 and N.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrate1Stereo)1028 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
1029 EXPECT_TRUE(SetupEngineWithSendStream());
1030 int channel_num = voe_.GetLastChannel();
1031 cricket::AudioSendParameters parameters;
1032 parameters.codecs.push_back(kOpusCodec);
1033 parameters.codecs[0].bitrate = 30000;
1034 parameters.codecs[0].params["stereo"] = "1";
1035 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1036 webrtc::CodecInst gcodec;
1037 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1038 EXPECT_EQ(2, gcodec.channels);
1039 EXPECT_EQ(30000, gcodec.rate);
1040 EXPECT_STREQ("opus", gcodec.plname);
1041 }
1042
1043 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1044 // Also test that the "maxaveragebitrate" can't be set to values outside the
1045 // range of 6000 and 510000
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusMaxAverageBitrate)1046 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1047 EXPECT_TRUE(SetupEngineWithSendStream());
1048 int channel_num = voe_.GetLastChannel();
1049 cricket::AudioSendParameters parameters;
1050 parameters.codecs.push_back(kOpusCodec);
1051 parameters.codecs[0].bitrate = 30000;
1052 webrtc::CodecInst gcodec;
1053
1054 // Ignore if less than 6000.
1055 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
1056 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1057 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1058 EXPECT_EQ(6000, gcodec.rate);
1059
1060 // Ignore if larger than 510000.
1061 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
1062 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1063 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1064 EXPECT_EQ(510000, gcodec.rate);
1065
1066 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
1067 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1068 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1069 EXPECT_EQ(200000, gcodec.rate);
1070 }
1071
1072 // Test that we can enable NACK with opus as caller.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackAsCaller)1073 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1074 EXPECT_TRUE(SetupEngineWithSendStream());
1075 int channel_num = voe_.GetLastChannel();
1076 cricket::AudioSendParameters parameters;
1077 parameters.codecs.push_back(kOpusCodec);
1078 parameters.codecs[0].AddFeedbackParam(
1079 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1080 cricket::kParamValueEmpty));
1081 EXPECT_FALSE(voe_.GetNACK(channel_num));
1082 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1083 EXPECT_TRUE(voe_.GetNACK(channel_num));
1084 }
1085
1086 // Test that we can enable NACK with opus as callee.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackAsCallee)1087 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1088 EXPECT_TRUE(SetupEngineWithRecvStream());
1089 int channel_num = voe_.GetLastChannel();
1090 cricket::AudioSendParameters parameters;
1091 parameters.codecs.push_back(kOpusCodec);
1092 parameters.codecs[0].AddFeedbackParam(
1093 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1094 cricket::kParamValueEmpty));
1095 EXPECT_FALSE(voe_.GetNACK(channel_num));
1096 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1097 EXPECT_FALSE(voe_.GetNACK(channel_num));
1098
1099 EXPECT_TRUE(channel_->AddSendStream(
1100 cricket::StreamParams::CreateLegacy(kSsrc1)));
1101 EXPECT_TRUE(voe_.GetNACK(voe_.GetLastChannel()));
1102 }
1103
1104 // Test that we can enable NACK on receive streams.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackRecvStreams)1105 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1106 EXPECT_TRUE(SetupEngineWithSendStream());
1107 int channel_num1 = voe_.GetLastChannel();
1108 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1109 int channel_num2 = voe_.GetLastChannel();
1110 cricket::AudioSendParameters parameters;
1111 parameters.codecs.push_back(kOpusCodec);
1112 parameters.codecs[0].AddFeedbackParam(
1113 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1114 cricket::kParamValueEmpty));
1115 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1116 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1117 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1118 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1119 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1120 }
1121
1122 // Test that we can disable NACK.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecDisableNack)1123 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1124 EXPECT_TRUE(SetupEngineWithSendStream());
1125 int channel_num = voe_.GetLastChannel();
1126 cricket::AudioSendParameters parameters;
1127 parameters.codecs.push_back(kOpusCodec);
1128 parameters.codecs[0].AddFeedbackParam(
1129 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1130 cricket::kParamValueEmpty));
1131 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1132 EXPECT_TRUE(voe_.GetNACK(channel_num));
1133
1134 parameters.codecs.clear();
1135 parameters.codecs.push_back(kOpusCodec);
1136 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1137 EXPECT_FALSE(voe_.GetNACK(channel_num));
1138 }
1139
1140 // Test that we can disable NACK on receive streams.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecDisableNackRecvStreams)1141 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1142 EXPECT_TRUE(SetupEngineWithSendStream());
1143 int channel_num1 = voe_.GetLastChannel();
1144 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1145 int channel_num2 = voe_.GetLastChannel();
1146 cricket::AudioSendParameters parameters;
1147 parameters.codecs.push_back(kOpusCodec);
1148 parameters.codecs[0].AddFeedbackParam(
1149 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1150 cricket::kParamValueEmpty));
1151 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1152 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1153 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1154
1155 parameters.codecs.clear();
1156 parameters.codecs.push_back(kOpusCodec);
1157 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1158 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1159 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1160 }
1161
1162 // Test that NACK is enabled on a new receive stream.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamEnableNack)1163 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1164 EXPECT_TRUE(SetupEngineWithSendStream());
1165 int channel_num = voe_.GetLastChannel();
1166 cricket::AudioSendParameters parameters;
1167 parameters.codecs.push_back(kIsacCodec);
1168 parameters.codecs.push_back(kCn16000Codec);
1169 parameters.codecs[0].AddFeedbackParam(
1170 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1171 cricket::kParamValueEmpty));
1172 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1173 EXPECT_TRUE(voe_.GetNACK(channel_num));
1174
1175 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1176 channel_num = voe_.GetLastChannel();
1177 EXPECT_TRUE(voe_.GetNACK(channel_num));
1178 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1179 channel_num = voe_.GetLastChannel();
1180 EXPECT_TRUE(voe_.GetNACK(channel_num));
1181 }
1182
1183 // Test that without useinbandfec, Opus FEC is off.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecNoOpusFec)1184 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
1185 EXPECT_TRUE(SetupEngineWithSendStream());
1186 int channel_num = voe_.GetLastChannel();
1187 cricket::AudioSendParameters parameters;
1188 parameters.codecs.push_back(kOpusCodec);
1189 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1190 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1191 }
1192
1193 // Test that with useinbandfec=0, Opus FEC is off.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusDisableFec)1194 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
1195 EXPECT_TRUE(SetupEngineWithSendStream());
1196 int channel_num = voe_.GetLastChannel();
1197 cricket::AudioSendParameters parameters;
1198 parameters.codecs.push_back(kOpusCodec);
1199 parameters.codecs[0].bitrate = 0;
1200 parameters.codecs[0].params["useinbandfec"] = "0";
1201 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1202 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1203 webrtc::CodecInst gcodec;
1204 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1205 EXPECT_STREQ("opus", gcodec.plname);
1206 EXPECT_EQ(1, gcodec.channels);
1207 EXPECT_EQ(32000, gcodec.rate);
1208 }
1209
1210 // Test that with useinbandfec=1, Opus FEC is on.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusEnableFec)1211 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
1212 EXPECT_TRUE(SetupEngineWithSendStream());
1213 int channel_num = voe_.GetLastChannel();
1214 cricket::AudioSendParameters parameters;
1215 parameters.codecs.push_back(kOpusCodec);
1216 parameters.codecs[0].bitrate = 0;
1217 parameters.codecs[0].params["useinbandfec"] = "1";
1218 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1219 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1220 webrtc::CodecInst gcodec;
1221 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1222 EXPECT_STREQ("opus", gcodec.plname);
1223 EXPECT_EQ(1, gcodec.channels);
1224 EXPECT_EQ(32000, gcodec.rate);
1225 }
1226
1227 // Test that with useinbandfec=1, stereo=1, Opus FEC is on.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusEnableFecStereo)1228 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
1229 EXPECT_TRUE(SetupEngineWithSendStream());
1230 int channel_num = voe_.GetLastChannel();
1231 cricket::AudioSendParameters parameters;
1232 parameters.codecs.push_back(kOpusCodec);
1233 parameters.codecs[0].bitrate = 0;
1234 parameters.codecs[0].params["stereo"] = "1";
1235 parameters.codecs[0].params["useinbandfec"] = "1";
1236 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1237 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1238 webrtc::CodecInst gcodec;
1239 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1240 EXPECT_STREQ("opus", gcodec.plname);
1241 EXPECT_EQ(2, gcodec.channels);
1242 EXPECT_EQ(64000, gcodec.rate);
1243 }
1244
1245 // Test that with non-Opus, codec FEC is off.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecIsacNoFec)1246 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
1247 EXPECT_TRUE(SetupEngineWithSendStream());
1248 int channel_num = voe_.GetLastChannel();
1249 cricket::AudioSendParameters parameters;
1250 parameters.codecs.push_back(kIsacCodec);
1251 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1252 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1253 }
1254
1255 // Test the with non-Opus, even if useinbandfec=1, FEC is off.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecIsacWithParamNoFec)1256 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1257 EXPECT_TRUE(SetupEngineWithSendStream());
1258 int channel_num = voe_.GetLastChannel();
1259 cricket::AudioSendParameters parameters;
1260 parameters.codecs.push_back(kIsacCodec);
1261 parameters.codecs[0].params["useinbandfec"] = "1";
1262 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1263 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1264 }
1265
1266 // Test that Opus FEC status can be changed.
TEST_F(WebRtcVoiceEngineTestFake,ChangeOpusFecStatus)1267 TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1268 EXPECT_TRUE(SetupEngineWithSendStream());
1269 int channel_num = voe_.GetLastChannel();
1270 cricket::AudioSendParameters parameters;
1271 parameters.codecs.push_back(kOpusCodec);
1272 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1273 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1274 parameters.codecs[0].params["useinbandfec"] = "1";
1275 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1276 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1277 }
1278
1279 // Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateNb)1280 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1281 EXPECT_TRUE(SetupEngineWithSendStream());
1282 int channel_num = voe_.GetLastChannel();
1283 cricket::AudioSendParameters parameters;
1284 parameters.codecs.push_back(kOpusCodec);
1285 parameters.codecs[0].bitrate = 0;
1286 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1287 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1288 EXPECT_EQ(cricket::kOpusBandwidthNb,
1289 voe_.GetMaxEncodingBandwidth(channel_num));
1290 webrtc::CodecInst gcodec;
1291 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1292 EXPECT_STREQ("opus", gcodec.plname);
1293
1294 EXPECT_EQ(12000, gcodec.rate);
1295 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1296 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1297 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1298 EXPECT_EQ(24000, gcodec.rate);
1299 }
1300
1301 // Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateMb)1302 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1303 EXPECT_TRUE(SetupEngineWithSendStream());
1304 int channel_num = voe_.GetLastChannel();
1305 cricket::AudioSendParameters parameters;
1306 parameters.codecs.push_back(kOpusCodec);
1307 parameters.codecs[0].bitrate = 0;
1308 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1309 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1310 EXPECT_EQ(cricket::kOpusBandwidthMb,
1311 voe_.GetMaxEncodingBandwidth(channel_num));
1312 webrtc::CodecInst gcodec;
1313 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1314 EXPECT_STREQ("opus", gcodec.plname);
1315
1316 EXPECT_EQ(20000, gcodec.rate);
1317 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1318 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1319 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1320 EXPECT_EQ(40000, gcodec.rate);
1321 }
1322
1323 // Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateWb)1324 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1325 EXPECT_TRUE(SetupEngineWithSendStream());
1326 int channel_num = voe_.GetLastChannel();
1327 cricket::AudioSendParameters parameters;
1328 parameters.codecs.push_back(kOpusCodec);
1329 parameters.codecs[0].bitrate = 0;
1330 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1331 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1332 EXPECT_EQ(cricket::kOpusBandwidthWb,
1333 voe_.GetMaxEncodingBandwidth(channel_num));
1334 webrtc::CodecInst gcodec;
1335 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1336 EXPECT_STREQ("opus", gcodec.plname);
1337
1338 EXPECT_EQ(20000, gcodec.rate);
1339 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1340 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1341 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1342 EXPECT_EQ(40000, gcodec.rate);
1343 }
1344
1345 // Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateSwb)1346 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1347 EXPECT_TRUE(SetupEngineWithSendStream());
1348 int channel_num = voe_.GetLastChannel();
1349 cricket::AudioSendParameters parameters;
1350 parameters.codecs.push_back(kOpusCodec);
1351 parameters.codecs[0].bitrate = 0;
1352 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1353 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1354 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1355 voe_.GetMaxEncodingBandwidth(channel_num));
1356 webrtc::CodecInst gcodec;
1357 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1358 EXPECT_STREQ("opus", gcodec.plname);
1359
1360 EXPECT_EQ(32000, gcodec.rate);
1361 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1362 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1363 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1364 EXPECT_EQ(64000, gcodec.rate);
1365 }
1366
1367 // Test 24000 < maxplaybackrate triggers Opus full band mode.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateFb)1368 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1369 EXPECT_TRUE(SetupEngineWithSendStream());
1370 int channel_num = voe_.GetLastChannel();
1371 cricket::AudioSendParameters parameters;
1372 parameters.codecs.push_back(kOpusCodec);
1373 parameters.codecs[0].bitrate = 0;
1374 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1375 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1376 EXPECT_EQ(cricket::kOpusBandwidthFb,
1377 voe_.GetMaxEncodingBandwidth(channel_num));
1378 webrtc::CodecInst gcodec;
1379 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1380 EXPECT_STREQ("opus", gcodec.plname);
1381
1382 EXPECT_EQ(32000, gcodec.rate);
1383 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1384 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1385 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1386 EXPECT_EQ(64000, gcodec.rate);
1387 }
1388
1389 // Test Opus that without maxplaybackrate, default playback rate is used.
TEST_F(WebRtcVoiceEngineTestFake,DefaultOpusMaxPlaybackRate)1390 TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1391 EXPECT_TRUE(SetupEngineWithSendStream());
1392 int channel_num = voe_.GetLastChannel();
1393 cricket::AudioSendParameters parameters;
1394 parameters.codecs.push_back(kOpusCodec);
1395 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1396 EXPECT_EQ(cricket::kOpusBandwidthFb,
1397 voe_.GetMaxEncodingBandwidth(channel_num));
1398 }
1399
1400 // Test the with non-Opus, maxplaybackrate has no effect.
TEST_F(WebRtcVoiceEngineTestFake,SetNonOpusMaxPlaybackRate)1401 TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1402 EXPECT_TRUE(SetupEngineWithSendStream());
1403 int channel_num = voe_.GetLastChannel();
1404 cricket::AudioSendParameters parameters;
1405 parameters.codecs.push_back(kIsacCodec);
1406 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1407 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1408 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1409 }
1410
1411 // Test maxplaybackrate can be set on two streams.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateOnTwoStreams)1412 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1413 EXPECT_TRUE(SetupEngineWithSendStream());
1414 int channel_num = voe_.GetLastChannel();
1415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kOpusCodec);
1417 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1418 // Default bandwidth is 24000.
1419 EXPECT_EQ(cricket::kOpusBandwidthFb,
1420 voe_.GetMaxEncodingBandwidth(channel_num));
1421
1422 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1423
1424 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1425 EXPECT_EQ(cricket::kOpusBandwidthNb,
1426 voe_.GetMaxEncodingBandwidth(channel_num));
1427
1428 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1429 channel_num = voe_.GetLastChannel();
1430 EXPECT_EQ(cricket::kOpusBandwidthNb,
1431 voe_.GetMaxEncodingBandwidth(channel_num));
1432 }
1433
1434 // Test that with usedtx=0, Opus DTX is off.
TEST_F(WebRtcVoiceEngineTestFake,DisableOpusDtxOnOpus)1435 TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1436 EXPECT_TRUE(SetupEngineWithSendStream());
1437 int channel_num = voe_.GetLastChannel();
1438 cricket::AudioSendParameters parameters;
1439 parameters.codecs.push_back(kOpusCodec);
1440 parameters.codecs[0].params["usedtx"] = "0";
1441 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1442 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1443 }
1444
1445 // Test that with usedtx=1, Opus DTX is on.
TEST_F(WebRtcVoiceEngineTestFake,EnableOpusDtxOnOpus)1446 TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1447 EXPECT_TRUE(SetupEngineWithSendStream());
1448 int channel_num = voe_.GetLastChannel();
1449 cricket::AudioSendParameters parameters;
1450 parameters.codecs.push_back(kOpusCodec);
1451 parameters.codecs[0].params["usedtx"] = "1";
1452 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1453 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1454 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1455 }
1456
1457 // Test that usedtx=1 works with stereo Opus.
TEST_F(WebRtcVoiceEngineTestFake,EnableOpusDtxOnOpusStereo)1458 TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1459 EXPECT_TRUE(SetupEngineWithSendStream());
1460 int channel_num = voe_.GetLastChannel();
1461 cricket::AudioSendParameters parameters;
1462 parameters.codecs.push_back(kOpusCodec);
1463 parameters.codecs[0].params["usedtx"] = "1";
1464 parameters.codecs[0].params["stereo"] = "1";
1465 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1466 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1467 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1468 }
1469
1470 // Test that usedtx=1 does not work with non Opus.
TEST_F(WebRtcVoiceEngineTestFake,CannotEnableOpusDtxOnNonOpus)1471 TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1472 EXPECT_TRUE(SetupEngineWithSendStream());
1473 int channel_num = voe_.GetLastChannel();
1474 cricket::AudioSendParameters parameters;
1475 parameters.codecs.push_back(kIsacCodec);
1476 parameters.codecs[0].params["usedtx"] = "1";
1477 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1478 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1479 }
1480
1481 // Test that we can switch back and forth between Opus and ISAC with CN.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsIsacOpusSwitching)1482 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
1483 EXPECT_TRUE(SetupEngineWithSendStream());
1484 int channel_num = voe_.GetLastChannel();
1485 cricket::AudioSendParameters opus_parameters;
1486 opus_parameters.codecs.push_back(kOpusCodec);
1487 EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1488 webrtc::CodecInst gcodec;
1489 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1490 EXPECT_EQ(111, gcodec.pltype);
1491 EXPECT_STREQ("opus", gcodec.plname);
1492
1493 cricket::AudioSendParameters isac_parameters;
1494 isac_parameters.codecs.push_back(kIsacCodec);
1495 isac_parameters.codecs.push_back(kCn16000Codec);
1496 isac_parameters.codecs.push_back(kOpusCodec);
1497 EXPECT_TRUE(channel_->SetSendParameters(isac_parameters));
1498 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499 EXPECT_EQ(103, gcodec.pltype);
1500 EXPECT_STREQ("ISAC", gcodec.plname);
1501
1502 EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1503 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1504 EXPECT_EQ(111, gcodec.pltype);
1505 EXPECT_STREQ("opus", gcodec.plname);
1506 }
1507
1508 // Test that we handle various ways of specifying bitrate.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBitrate)1509 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1510 EXPECT_TRUE(SetupEngineWithSendStream());
1511 int channel_num = voe_.GetLastChannel();
1512 cricket::AudioSendParameters parameters;
1513 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
1514 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1515 webrtc::CodecInst gcodec;
1516 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1517 EXPECT_EQ(103, gcodec.pltype);
1518 EXPECT_STREQ("ISAC", gcodec.plname);
1519 EXPECT_EQ(32000, gcodec.rate);
1520
1521 parameters.codecs[0].bitrate = 0; // bitrate == default
1522 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1523 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1524 EXPECT_EQ(103, gcodec.pltype);
1525 EXPECT_STREQ("ISAC", gcodec.plname);
1526 EXPECT_EQ(-1, gcodec.rate);
1527
1528 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
1529 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1530 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1531 EXPECT_EQ(103, gcodec.pltype);
1532 EXPECT_STREQ("ISAC", gcodec.plname);
1533 EXPECT_EQ(28000, gcodec.rate);
1534
1535 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
1536 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1537 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1538 EXPECT_EQ(0, gcodec.pltype);
1539 EXPECT_STREQ("PCMU", gcodec.plname);
1540 EXPECT_EQ(64000, gcodec.rate);
1541
1542 parameters.codecs[0].bitrate = 0; // bitrate == default
1543 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1544 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1545 EXPECT_EQ(0, gcodec.pltype);
1546 EXPECT_STREQ("PCMU", gcodec.plname);
1547 EXPECT_EQ(64000, gcodec.rate);
1548
1549 parameters.codecs[0] = kOpusCodec;
1550 parameters.codecs[0].bitrate = 0; // bitrate == default
1551 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1552 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1553 EXPECT_EQ(111, gcodec.pltype);
1554 EXPECT_STREQ("opus", gcodec.plname);
1555 EXPECT_EQ(32000, gcodec.rate);
1556 }
1557
1558 // Test that we could set packet size specified in kCodecParamPTime.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsPTimeAsPacketSize)1559 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1560 EXPECT_TRUE(SetupEngineWithSendStream());
1561 int channel_num = voe_.GetLastChannel();
1562 cricket::AudioSendParameters parameters;
1563 parameters.codecs.push_back(kOpusCodec);
1564 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1565 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1566 webrtc::CodecInst gcodec;
1567 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1568 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1569
1570 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
1571 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1572 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1573 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1574
1575 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
1576 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1577 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1578 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1579
1580 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1581 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1582 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1583 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1584 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1585
1586 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1587 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1588 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1589 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1590 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1591 }
1592
1593 // Test that we fail if no codecs are specified.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsNoCodecs)1594 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1595 EXPECT_TRUE(SetupEngineWithSendStream());
1596 cricket::AudioSendParameters parameters;
1597 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1598 }
1599
1600 // Test that we can set send codecs even with telephone-event codec as the first
1601 // one on the list.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsDTMFOnTop)1602 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1603 EXPECT_TRUE(SetupEngineWithSendStream());
1604 int channel_num = voe_.GetLastChannel();
1605 cricket::AudioSendParameters parameters;
1606 parameters.codecs.push_back(kTelephoneEventCodec);
1607 parameters.codecs.push_back(kIsacCodec);
1608 parameters.codecs.push_back(kPcmuCodec);
1609 parameters.codecs[0].id = 98; // DTMF
1610 parameters.codecs[1].id = 96;
1611 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1612 webrtc::CodecInst gcodec;
1613 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1614 EXPECT_EQ(96, gcodec.pltype);
1615 EXPECT_STREQ("ISAC", gcodec.plname);
1616 EXPECT_TRUE(channel_->CanInsertDtmf());
1617 }
1618
1619 // Test that we can set send codecs even with CN codec as the first
1620 // one on the list.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNOnTop)1621 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1622 EXPECT_TRUE(SetupEngineWithSendStream());
1623 int channel_num = voe_.GetLastChannel();
1624 cricket::AudioSendParameters parameters;
1625 parameters.codecs.push_back(kCn16000Codec);
1626 parameters.codecs.push_back(kIsacCodec);
1627 parameters.codecs.push_back(kPcmuCodec);
1628 parameters.codecs[0].id = 98; // wideband CN
1629 parameters.codecs[1].id = 96;
1630 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1631 webrtc::CodecInst gcodec;
1632 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1633 EXPECT_EQ(96, gcodec.pltype);
1634 EXPECT_STREQ("ISAC", gcodec.plname);
1635 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1636 }
1637
1638 // Test that we set VAD and DTMF types correctly as caller.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNandDTMFAsCaller)1639 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1640 EXPECT_TRUE(SetupEngineWithSendStream());
1641 int channel_num = voe_.GetLastChannel();
1642 cricket::AudioSendParameters parameters;
1643 parameters.codecs.push_back(kIsacCodec);
1644 parameters.codecs.push_back(kPcmuCodec);
1645 // TODO(juberti): cn 32000
1646 parameters.codecs.push_back(kCn16000Codec);
1647 parameters.codecs.push_back(kCn8000Codec);
1648 parameters.codecs.push_back(kTelephoneEventCodec);
1649 parameters.codecs.push_back(kRedCodec);
1650 parameters.codecs[0].id = 96;
1651 parameters.codecs[2].id = 97; // wideband CN
1652 parameters.codecs[4].id = 98; // DTMF
1653 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1654 webrtc::CodecInst gcodec;
1655 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1656 EXPECT_EQ(96, gcodec.pltype);
1657 EXPECT_STREQ("ISAC", gcodec.plname);
1658 EXPECT_TRUE(voe_.GetVAD(channel_num));
1659 EXPECT_FALSE(voe_.GetRED(channel_num));
1660 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1661 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1662 EXPECT_TRUE(channel_->CanInsertDtmf());
1663 }
1664
1665 // Test that we set VAD and DTMF types correctly as callee.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNandDTMFAsCallee)1666 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1667 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1668 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1669 EXPECT_TRUE(channel_ != nullptr);
1670
1671 cricket::AudioSendParameters parameters;
1672 parameters.codecs.push_back(kIsacCodec);
1673 parameters.codecs.push_back(kPcmuCodec);
1674 // TODO(juberti): cn 32000
1675 parameters.codecs.push_back(kCn16000Codec);
1676 parameters.codecs.push_back(kCn8000Codec);
1677 parameters.codecs.push_back(kTelephoneEventCodec);
1678 parameters.codecs.push_back(kRedCodec);
1679 parameters.codecs[0].id = 96;
1680 parameters.codecs[2].id = 97; // wideband CN
1681 parameters.codecs[4].id = 98; // DTMF
1682 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1683 EXPECT_TRUE(channel_->AddSendStream(
1684 cricket::StreamParams::CreateLegacy(kSsrc1)));
1685 int channel_num = voe_.GetLastChannel();
1686
1687 webrtc::CodecInst gcodec;
1688 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1689 EXPECT_EQ(96, gcodec.pltype);
1690 EXPECT_STREQ("ISAC", gcodec.plname);
1691 EXPECT_TRUE(voe_.GetVAD(channel_num));
1692 EXPECT_FALSE(voe_.GetRED(channel_num));
1693 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1694 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1695 EXPECT_TRUE(channel_->CanInsertDtmf());
1696 }
1697
1698 // Test that we only apply VAD if we have a CN codec that matches the
1699 // send codec clockrate.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNNoMatch)1700 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1701 EXPECT_TRUE(SetupEngineWithSendStream());
1702 int channel_num = voe_.GetLastChannel();
1703 cricket::AudioSendParameters parameters;
1704 // Set ISAC(16K) and CN(16K). VAD should be activated.
1705 parameters.codecs.push_back(kIsacCodec);
1706 parameters.codecs.push_back(kCn16000Codec);
1707 parameters.codecs[1].id = 97;
1708 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1709 webrtc::CodecInst gcodec;
1710 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1711 EXPECT_STREQ("ISAC", gcodec.plname);
1712 EXPECT_TRUE(voe_.GetVAD(channel_num));
1713 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1714 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1715 parameters.codecs[0] = kPcmuCodec;
1716 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1717 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1718 EXPECT_STREQ("PCMU", gcodec.plname);
1719 EXPECT_FALSE(voe_.GetVAD(channel_num));
1720 // Set PCMU(8K) and CN(8K). VAD should be activated.
1721 parameters.codecs[1] = kCn8000Codec;
1722 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1723 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1724 EXPECT_STREQ("PCMU", gcodec.plname);
1725 EXPECT_TRUE(voe_.GetVAD(channel_num));
1726 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1727 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1728 parameters.codecs[0] = kIsacCodec;
1729 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1730 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1731 EXPECT_STREQ("ISAC", gcodec.plname);
1732 EXPECT_FALSE(voe_.GetVAD(channel_num));
1733 }
1734
1735 // Test that we perform case-insensitive matching of codec names.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCaseInsensitive)1736 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1737 EXPECT_TRUE(SetupEngineWithSendStream());
1738 int channel_num = voe_.GetLastChannel();
1739 cricket::AudioSendParameters parameters;
1740 parameters.codecs.push_back(kIsacCodec);
1741 parameters.codecs.push_back(kPcmuCodec);
1742 parameters.codecs.push_back(kCn16000Codec);
1743 parameters.codecs.push_back(kCn8000Codec);
1744 parameters.codecs.push_back(kTelephoneEventCodec);
1745 parameters.codecs.push_back(kRedCodec);
1746 parameters.codecs[0].name = "iSaC";
1747 parameters.codecs[0].id = 96;
1748 parameters.codecs[2].id = 97; // wideband CN
1749 parameters.codecs[4].id = 98; // DTMF
1750 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1751 webrtc::CodecInst gcodec;
1752 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1753 EXPECT_EQ(96, gcodec.pltype);
1754 EXPECT_STREQ("ISAC", gcodec.plname);
1755 EXPECT_TRUE(voe_.GetVAD(channel_num));
1756 EXPECT_FALSE(voe_.GetRED(channel_num));
1757 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1758 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1759 EXPECT_TRUE(channel_->CanInsertDtmf());
1760 }
1761
1762 // Test that we set up RED correctly as caller.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDAsCaller)1763 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1764 EXPECT_TRUE(SetupEngineWithSendStream());
1765 int channel_num = voe_.GetLastChannel();
1766 cricket::AudioSendParameters parameters;
1767 parameters.codecs.push_back(kRedCodec);
1768 parameters.codecs.push_back(kIsacCodec);
1769 parameters.codecs.push_back(kPcmuCodec);
1770 parameters.codecs[0].id = 127;
1771 parameters.codecs[0].params[""] = "96/96";
1772 parameters.codecs[1].id = 96;
1773 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1774 webrtc::CodecInst gcodec;
1775 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1776 EXPECT_EQ(96, gcodec.pltype);
1777 EXPECT_STREQ("ISAC", gcodec.plname);
1778 EXPECT_TRUE(voe_.GetRED(channel_num));
1779 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1780 }
1781
1782 // Test that we set up RED correctly as callee.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDAsCallee)1783 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1784 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1785 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1786 EXPECT_TRUE(channel_ != nullptr);
1787
1788 cricket::AudioSendParameters parameters;
1789 parameters.codecs.push_back(kRedCodec);
1790 parameters.codecs.push_back(kIsacCodec);
1791 parameters.codecs.push_back(kPcmuCodec);
1792 parameters.codecs[0].id = 127;
1793 parameters.codecs[0].params[""] = "96/96";
1794 parameters.codecs[1].id = 96;
1795 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1796 EXPECT_TRUE(channel_->AddSendStream(
1797 cricket::StreamParams::CreateLegacy(kSsrc1)));
1798 int channel_num = voe_.GetLastChannel();
1799 webrtc::CodecInst gcodec;
1800 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1801 EXPECT_EQ(96, gcodec.pltype);
1802 EXPECT_STREQ("ISAC", gcodec.plname);
1803 EXPECT_TRUE(voe_.GetRED(channel_num));
1804 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1805 }
1806
1807 // Test that we set up RED correctly if params are omitted.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDNoParams)1808 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1809 EXPECT_TRUE(SetupEngineWithSendStream());
1810 int channel_num = voe_.GetLastChannel();
1811 cricket::AudioSendParameters parameters;
1812 parameters.codecs.push_back(kRedCodec);
1813 parameters.codecs.push_back(kIsacCodec);
1814 parameters.codecs.push_back(kPcmuCodec);
1815 parameters.codecs[0].id = 127;
1816 parameters.codecs[1].id = 96;
1817 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1818 webrtc::CodecInst gcodec;
1819 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1820 EXPECT_EQ(96, gcodec.pltype);
1821 EXPECT_STREQ("ISAC", gcodec.plname);
1822 EXPECT_TRUE(voe_.GetRED(channel_num));
1823 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1824 }
1825
1826 // Test that we ignore RED if the parameters aren't named the way we expect.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED1)1827 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1828 EXPECT_TRUE(SetupEngineWithSendStream());
1829 int channel_num = voe_.GetLastChannel();
1830 cricket::AudioSendParameters parameters;
1831 parameters.codecs.push_back(kRedCodec);
1832 parameters.codecs.push_back(kIsacCodec);
1833 parameters.codecs.push_back(kPcmuCodec);
1834 parameters.codecs[0].id = 127;
1835 parameters.codecs[0].params["ABC"] = "96/96";
1836 parameters.codecs[1].id = 96;
1837 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1838 webrtc::CodecInst gcodec;
1839 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1840 EXPECT_EQ(96, gcodec.pltype);
1841 EXPECT_STREQ("ISAC", gcodec.plname);
1842 EXPECT_FALSE(voe_.GetRED(channel_num));
1843 }
1844
1845 // Test that we ignore RED if it uses different primary/secondary encoding.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED2)1846 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1847 EXPECT_TRUE(SetupEngineWithSendStream());
1848 int channel_num = voe_.GetLastChannel();
1849 cricket::AudioSendParameters parameters;
1850 parameters.codecs.push_back(kRedCodec);
1851 parameters.codecs.push_back(kIsacCodec);
1852 parameters.codecs.push_back(kPcmuCodec);
1853 parameters.codecs[0].id = 127;
1854 parameters.codecs[0].params[""] = "96/0";
1855 parameters.codecs[1].id = 96;
1856 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1857 webrtc::CodecInst gcodec;
1858 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1859 EXPECT_EQ(96, gcodec.pltype);
1860 EXPECT_STREQ("ISAC", gcodec.plname);
1861 EXPECT_FALSE(voe_.GetRED(channel_num));
1862 }
1863
1864 // Test that we ignore RED if it uses more than 2 encodings.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED3)1865 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1866 EXPECT_TRUE(SetupEngineWithSendStream());
1867 int channel_num = voe_.GetLastChannel();
1868 cricket::AudioSendParameters parameters;
1869 parameters.codecs.push_back(kRedCodec);
1870 parameters.codecs.push_back(kIsacCodec);
1871 parameters.codecs.push_back(kPcmuCodec);
1872 parameters.codecs[0].id = 127;
1873 parameters.codecs[0].params[""] = "96/96/96";
1874 parameters.codecs[1].id = 96;
1875 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1876 webrtc::CodecInst gcodec;
1877 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1878 EXPECT_EQ(96, gcodec.pltype);
1879 EXPECT_STREQ("ISAC", gcodec.plname);
1880 EXPECT_FALSE(voe_.GetRED(channel_num));
1881 }
1882
1883 // Test that we ignore RED if it has bogus codec ids.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED4)1884 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1885 EXPECT_TRUE(SetupEngineWithSendStream());
1886 int channel_num = voe_.GetLastChannel();
1887 cricket::AudioSendParameters parameters;
1888 parameters.codecs.push_back(kRedCodec);
1889 parameters.codecs.push_back(kIsacCodec);
1890 parameters.codecs.push_back(kPcmuCodec);
1891 parameters.codecs[0].id = 127;
1892 parameters.codecs[0].params[""] = "ABC/ABC";
1893 parameters.codecs[1].id = 96;
1894 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1895 webrtc::CodecInst gcodec;
1896 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1897 EXPECT_EQ(96, gcodec.pltype);
1898 EXPECT_STREQ("ISAC", gcodec.plname);
1899 EXPECT_FALSE(voe_.GetRED(channel_num));
1900 }
1901
1902 // Test that we ignore RED if it refers to a codec that is not present.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED5)1903 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1904 EXPECT_TRUE(SetupEngineWithSendStream());
1905 int channel_num = voe_.GetLastChannel();
1906 cricket::AudioSendParameters parameters;
1907 parameters.codecs.push_back(kRedCodec);
1908 parameters.codecs.push_back(kIsacCodec);
1909 parameters.codecs.push_back(kPcmuCodec);
1910 parameters.codecs[0].id = 127;
1911 parameters.codecs[0].params[""] = "97/97";
1912 parameters.codecs[1].id = 96;
1913 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1914 webrtc::CodecInst gcodec;
1915 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1916 EXPECT_EQ(96, gcodec.pltype);
1917 EXPECT_STREQ("ISAC", gcodec.plname);
1918 EXPECT_FALSE(voe_.GetRED(channel_num));
1919 }
1920
1921 // Test support for audio level header extension.
TEST_F(WebRtcVoiceEngineTestFake,SendAudioLevelHeaderExtensions)1922 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1923 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1924 }
TEST_F(WebRtcVoiceEngineTestFake,RecvAudioLevelHeaderExtensions)1925 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1926 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1927 }
1928
1929 // Test support for absolute send time header extension.
TEST_F(WebRtcVoiceEngineTestFake,SendAbsoluteSendTimeHeaderExtensions)1930 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1931 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1932 }
TEST_F(WebRtcVoiceEngineTestFake,RecvAbsoluteSendTimeHeaderExtensions)1933 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1934 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1935 }
1936
1937 // Test that we can create a channel and start sending on it.
TEST_F(WebRtcVoiceEngineTestFake,Send)1938 TEST_F(WebRtcVoiceEngineTestFake, Send) {
1939 EXPECT_TRUE(SetupEngineWithSendStream());
1940 int channel_num = voe_.GetLastChannel();
1941 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1942 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1943 EXPECT_TRUE(voe_.GetSend(channel_num));
1944 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1945 EXPECT_FALSE(voe_.GetSend(channel_num));
1946 }
1947
1948 // Test that we can create a channel and start playing out on it.
TEST_F(WebRtcVoiceEngineTestFake,Playout)1949 TEST_F(WebRtcVoiceEngineTestFake, Playout) {
1950 EXPECT_TRUE(SetupEngineWithRecvStream());
1951 int channel_num = voe_.GetLastChannel();
1952 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1953 EXPECT_TRUE(channel_->SetPlayout(true));
1954 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1955 EXPECT_TRUE(channel_->SetPlayout(false));
1956 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1957 }
1958
1959 // Test that we can add and remove send streams.
TEST_F(WebRtcVoiceEngineTestFake,CreateAndDeleteMultipleSendStreams)1960 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1961 SetupForMultiSendStream();
1962
1963 // Set the global state for sending.
1964 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1965
1966 for (uint32_t ssrc : kSsrcs4) {
1967 EXPECT_TRUE(channel_->AddSendStream(
1968 cricket::StreamParams::CreateLegacy(ssrc)));
1969 // Verify that we are in a sending state for all the created streams.
1970 EXPECT_TRUE(voe_.GetSend(GetSendStreamConfig(ssrc).voe_channel_id));
1971 }
1972 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
1973
1974 // Delete the send streams.
1975 for (uint32_t ssrc : kSsrcs4) {
1976 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
1977 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
1978 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
1979 }
1980 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
1981 }
1982
1983 // Test SetSendCodecs correctly configure the codecs in all send streams.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsWithMultipleSendStreams)1984 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1985 SetupForMultiSendStream();
1986
1987 // Create send streams.
1988 for (uint32_t ssrc : kSsrcs4) {
1989 EXPECT_TRUE(channel_->AddSendStream(
1990 cricket::StreamParams::CreateLegacy(ssrc)));
1991 }
1992
1993 cricket::AudioSendParameters parameters;
1994 // Set ISAC(16K) and CN(16K). VAD should be activated.
1995 parameters.codecs.push_back(kIsacCodec);
1996 parameters.codecs.push_back(kCn16000Codec);
1997 parameters.codecs[1].id = 97;
1998 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1999
2000 // Verify ISAC and VAD are corrected configured on all send channels.
2001 webrtc::CodecInst gcodec;
2002 for (uint32_t ssrc : kSsrcs4) {
2003 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2004 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2005 EXPECT_STREQ("ISAC", gcodec.plname);
2006 EXPECT_TRUE(voe_.GetVAD(channel_num));
2007 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
2008 }
2009
2010 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
2011 parameters.codecs[0] = kPcmuCodec;
2012 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2013 for (uint32_t ssrc : kSsrcs4) {
2014 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2015 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2016 EXPECT_STREQ("PCMU", gcodec.plname);
2017 EXPECT_FALSE(voe_.GetVAD(channel_num));
2018 }
2019 }
2020
2021 // Test we can SetSend on all send streams correctly.
TEST_F(WebRtcVoiceEngineTestFake,SetSendWithMultipleSendStreams)2022 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2023 SetupForMultiSendStream();
2024
2025 // Create the send channels and they should be a SEND_NOTHING date.
2026 for (uint32_t ssrc : kSsrcs4) {
2027 EXPECT_TRUE(channel_->AddSendStream(
2028 cricket::StreamParams::CreateLegacy(ssrc)));
2029 int channel_num = voe_.GetLastChannel();
2030 EXPECT_FALSE(voe_.GetSend(channel_num));
2031 }
2032
2033 // Set the global state for starting sending.
2034 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2035 for (uint32_t ssrc : kSsrcs4) {
2036 // Verify that we are in a sending state for all the send streams.
2037 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2038 EXPECT_TRUE(voe_.GetSend(channel_num));
2039 }
2040
2041 // Set the global state for stopping sending.
2042 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2043 for (uint32_t ssrc : kSsrcs4) {
2044 // Verify that we are in a stop state for all the send streams.
2045 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2046 EXPECT_FALSE(voe_.GetSend(channel_num));
2047 }
2048 }
2049
2050 // Test we can set the correct statistics on all send streams.
TEST_F(WebRtcVoiceEngineTestFake,GetStatsWithMultipleSendStreams)2051 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2052 SetupForMultiSendStream();
2053
2054 // Create send streams.
2055 for (uint32_t ssrc : kSsrcs4) {
2056 EXPECT_TRUE(channel_->AddSendStream(
2057 cricket::StreamParams::CreateLegacy(ssrc)));
2058 }
2059 SetAudioSendStreamStats();
2060
2061 // Create a receive stream to check that none of the send streams end up in
2062 // the receive stream stats.
2063 EXPECT_TRUE(channel_->AddRecvStream(
2064 cricket::StreamParams::CreateLegacy(kSsrc2)));
2065 // We need send codec to be set to get all stats.
2066 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2067 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2068
2069 // Check stats for the added streams.
2070 {
2071 cricket::VoiceMediaInfo info;
2072 EXPECT_EQ(true, channel_->GetStats(&info));
2073
2074 // We have added 4 send streams. We should see empty stats for all.
2075 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2076 for (const auto& sender : info.senders) {
2077 VerifyVoiceSenderInfo(sender, false);
2078 }
2079
2080 // We have added one receive stream. We should see empty stats.
2081 EXPECT_EQ(info.receivers.size(), 1u);
2082 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2083 }
2084
2085 // Remove the kSsrc2 stream. No receiver stats.
2086 {
2087 cricket::VoiceMediaInfo info;
2088 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2089 EXPECT_EQ(true, channel_->GetStats(&info));
2090 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2091 EXPECT_EQ(0u, info.receivers.size());
2092 }
2093
2094 // Deliver a new packet - a default receive stream should be created and we
2095 // should see stats again.
2096 {
2097 cricket::VoiceMediaInfo info;
2098 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2099 SetAudioReceiveStreamStats();
2100 EXPECT_EQ(true, channel_->GetStats(&info));
2101 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2102 EXPECT_EQ(1u, info.receivers.size());
2103 VerifyVoiceReceiverInfo(info.receivers[0]);
2104 }
2105 }
2106
2107 // Test that we can add and remove receive streams, and do proper send/playout.
2108 // We can receive on multiple streams while sending one stream.
TEST_F(WebRtcVoiceEngineTestFake,PlayoutWithMultipleStreams)2109 TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
2110 EXPECT_TRUE(SetupEngineWithSendStream());
2111 int channel_num1 = voe_.GetLastChannel();
2112
2113 // Start playout without a receive stream.
2114 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2115 EXPECT_TRUE(channel_->SetPlayout(true));
2116 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2117
2118 // Adding another stream should enable playout on the new stream only.
2119 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2120 int channel_num2 = voe_.GetLastChannel();
2121 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2122 EXPECT_TRUE(voe_.GetSend(channel_num1));
2123 EXPECT_FALSE(voe_.GetSend(channel_num2));
2124
2125 // Make sure only the new stream is played out.
2126 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2127 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2128
2129 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2130 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2131 int channel_num3 = voe_.GetLastChannel();
2132 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2133 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2134 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2135 EXPECT_FALSE(voe_.GetSend(channel_num3));
2136
2137 // Stop sending.
2138 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2139 EXPECT_FALSE(voe_.GetSend(channel_num1));
2140 EXPECT_FALSE(voe_.GetSend(channel_num2));
2141 EXPECT_FALSE(voe_.GetSend(channel_num3));
2142
2143 // Stop playout.
2144 EXPECT_TRUE(channel_->SetPlayout(false));
2145 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2146 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2147 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2148
2149 // Restart playout and make sure only recv streams are played out.
2150 EXPECT_TRUE(channel_->SetPlayout(true));
2151 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2152 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2153 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2154
2155 // Now remove the recv streams and verify that the send stream doesn't play.
2156 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2157 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2158 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2159 }
2160
2161 // Test that we can create a channel configured for Codian bridges,
2162 // and start sending on it.
TEST_F(WebRtcVoiceEngineTestFake,CodianSend)2163 TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
2164 EXPECT_TRUE(SetupEngineWithSendStream());
2165 cricket::AudioOptions options_adjust_agc;
2166 options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
2167 int channel_num = voe_.GetLastChannel();
2168 webrtc::AgcConfig agc_config;
2169 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2170 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2171 send_parameters_.options = options_adjust_agc;
2172 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2173 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2174 EXPECT_TRUE(voe_.GetSend(channel_num));
2175 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2176 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2177 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2178 EXPECT_FALSE(voe_.GetSend(channel_num));
2179 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2180 }
2181
TEST_F(WebRtcVoiceEngineTestFake,TxAgcConfigViaOptions)2182 TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2183 EXPECT_TRUE(SetupEngineWithSendStream());
2184 webrtc::AgcConfig agc_config;
2185 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2186 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2187 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2188 send_parameters_.options.tx_agc_digital_compression_gain =
2189 rtc::Optional<uint16_t>(9);
2190 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2191 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2192 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2193 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2194 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2195 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2196 EXPECT_TRUE(agc_config.limiterEnable);
2197
2198 // Check interaction with adjust_agc_delta. Both should be respected, for
2199 // backwards compatibility.
2200 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2201 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2202 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2203 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2204 }
2205
TEST_F(WebRtcVoiceEngineTestFake,SampleRatesViaOptions)2206 TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2207 EXPECT_TRUE(SetupEngineWithSendStream());
2208 send_parameters_.options.recording_sample_rate =
2209 rtc::Optional<uint32_t>(48000);
2210 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
2211 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2212
2213 unsigned int recording_sample_rate, playout_sample_rate;
2214 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2215 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2216 EXPECT_EQ(48000u, recording_sample_rate);
2217 EXPECT_EQ(44100u, playout_sample_rate);
2218 }
2219
2220 // Test that we can set the outgoing SSRC properly.
2221 // SSRC is set in SetupEngine by calling AddSendStream.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrc)2222 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2223 EXPECT_TRUE(SetupEngineWithSendStream());
2224 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2225 }
2226
TEST_F(WebRtcVoiceEngineTestFake,GetStats)2227 TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2228 // Setup. We need send codec to be set to get all stats.
2229 EXPECT_TRUE(SetupEngineWithSendStream());
2230 SetAudioSendStreamStats();
2231 // SetupEngineWithSendStream adds a send stream with kSsrc1, so the receive
2232 // stream has to use a different SSRC.
2233 EXPECT_TRUE(channel_->AddRecvStream(
2234 cricket::StreamParams::CreateLegacy(kSsrc2)));
2235 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2236 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2237
2238 // Check stats for the added streams.
2239 {
2240 cricket::VoiceMediaInfo info;
2241 EXPECT_EQ(true, channel_->GetStats(&info));
2242
2243 // We have added one send stream. We should see the stats we've set.
2244 EXPECT_EQ(1u, info.senders.size());
2245 VerifyVoiceSenderInfo(info.senders[0], false);
2246 // We have added one receive stream. We should see empty stats.
2247 EXPECT_EQ(info.receivers.size(), 1u);
2248 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2249 }
2250
2251 // Start sending - this affects some reported stats.
2252 {
2253 cricket::VoiceMediaInfo info;
2254 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2255 EXPECT_EQ(true, channel_->GetStats(&info));
2256 VerifyVoiceSenderInfo(info.senders[0], true);
2257 }
2258
2259 // Remove the kSsrc2 stream. No receiver stats.
2260 {
2261 cricket::VoiceMediaInfo info;
2262 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2263 EXPECT_EQ(true, channel_->GetStats(&info));
2264 EXPECT_EQ(1u, info.senders.size());
2265 EXPECT_EQ(0u, info.receivers.size());
2266 }
2267
2268 // Deliver a new packet - a default receive stream should be created and we
2269 // should see stats again.
2270 {
2271 cricket::VoiceMediaInfo info;
2272 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2273 SetAudioReceiveStreamStats();
2274 EXPECT_EQ(true, channel_->GetStats(&info));
2275 EXPECT_EQ(1u, info.senders.size());
2276 EXPECT_EQ(1u, info.receivers.size());
2277 VerifyVoiceReceiverInfo(info.receivers[0]);
2278 }
2279 }
2280
2281 // Test that we can set the outgoing SSRC properly with multiple streams.
2282 // SSRC is set in SetupEngine by calling AddSendStream.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrcWithMultipleStreams)2283 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2284 EXPECT_TRUE(SetupEngineWithSendStream());
2285 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2286 EXPECT_TRUE(channel_->AddRecvStream(
2287 cricket::StreamParams::CreateLegacy(kSsrc2)));
2288 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
2289 }
2290
2291 // Test that the local SSRC is the same on sending and receiving channels if the
2292 // receive channel is created before the send channel.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrcAfterCreatingReceiveChannel)2293 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2294 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2295 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
2296
2297 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2298 int receive_channel_num = voe_.GetLastChannel();
2299 EXPECT_TRUE(channel_->AddSendStream(
2300 cricket::StreamParams::CreateLegacy(1234)));
2301
2302 EXPECT_TRUE(call_.GetAudioSendStream(1234));
2303 EXPECT_EQ(1234U, voe_.GetLocalSSRC(receive_channel_num));
2304 }
2305
2306 // Test that we can properly receive packets.
TEST_F(WebRtcVoiceEngineTestFake,Recv)2307 TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2308 EXPECT_TRUE(SetupEngine());
2309 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2310 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2311 int channel_num = voe_.GetLastChannel();
2312 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2313 }
2314
2315 // Test that we can properly receive packets on multiple streams.
TEST_F(WebRtcVoiceEngineTestFake,RecvWithMultipleStreams)2316 TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2317 EXPECT_TRUE(SetupEngine());
2318 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2319 int channel_num1 = voe_.GetLastChannel();
2320 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2321 int channel_num2 = voe_.GetLastChannel();
2322 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2323 int channel_num3 = voe_.GetLastChannel();
2324 // Create packets with the right SSRCs.
2325 char packets[4][sizeof(kPcmuFrame)];
2326 for (size_t i = 0; i < arraysize(packets); ++i) {
2327 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2328 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
2329 }
2330 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2331 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2332 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2333
2334 DeliverPacket(packets[0], sizeof(packets[0]));
2335 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2336 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2337 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2338
2339 DeliverPacket(packets[1], sizeof(packets[1]));
2340 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1], sizeof(packets[1])));
2341 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2342 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2343
2344 DeliverPacket(packets[2], sizeof(packets[2]));
2345 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2346 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2], sizeof(packets[2])));
2347 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2348
2349 DeliverPacket(packets[3], sizeof(packets[3]));
2350 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2351 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2352 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3], sizeof(packets[3])));
2353
2354 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2355 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2356 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2357 }
2358
2359 // Test that receiving on an unsignalled stream works (default channel will be
2360 // created).
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalled)2361 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
2362 EXPECT_TRUE(SetupEngine());
2363 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2364 int channel_num = voe_.GetLastChannel();
2365 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2366 }
2367
2368 // Test that receiving on an unsignalled stream works (default channel will be
2369 // created), and that packets will be forwarded to the default channel
2370 // regardless of their SSRCs.
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalledWithSsrcSwitch)2371 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
2372 EXPECT_TRUE(SetupEngine());
2373 char packet[sizeof(kPcmuFrame)];
2374 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2375
2376 // Note that the first unknown SSRC cannot be 0, because we only support
2377 // creating receive streams for SSRC!=0.
2378 DeliverPacket(packet, sizeof(packet));
2379 int channel_num = voe_.GetLastChannel();
2380 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2381 // Once we have the default channel, SSRC==0 will be ok.
2382 for (uint32_t ssrc = 0; ssrc < 10; ++ssrc) {
2383 rtc::SetBE32(&packet[8], ssrc);
2384 DeliverPacket(packet, sizeof(packet));
2385 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2386 }
2387 }
2388
2389 // Test that a default channel is created even after a signalled stream has been
2390 // added, and that this stream will get any packets for unknown SSRCs.
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalledAfterSignalled)2391 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
2392 EXPECT_TRUE(SetupEngine());
2393 char packet[sizeof(kPcmuFrame)];
2394 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2395
2396 // Add a known stream, send packet and verify we got it.
2397 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2398 int signalled_channel_num = voe_.GetLastChannel();
2399 DeliverPacket(packet, sizeof(packet));
2400 EXPECT_TRUE(voe_.CheckPacket(signalled_channel_num, packet, sizeof(packet)));
2401
2402 // Note that the first unknown SSRC cannot be 0, because we only support
2403 // creating receive streams for SSRC!=0.
2404 rtc::SetBE32(&packet[8], 7011);
2405 DeliverPacket(packet, sizeof(packet));
2406 int channel_num = voe_.GetLastChannel();
2407 EXPECT_NE(channel_num, signalled_channel_num);
2408 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2409 // Once we have the default channel, SSRC==0 will be ok.
2410 for (uint32_t ssrc = 0; ssrc < 20; ssrc += 2) {
2411 rtc::SetBE32(&packet[8], ssrc);
2412 DeliverPacket(packet, sizeof(packet));
2413 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2414 }
2415 }
2416
2417 // Test that we properly handle failures to add a receive stream.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamFail)2418 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
2419 EXPECT_TRUE(SetupEngine());
2420 voe_.set_fail_create_channel(true);
2421 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2422 }
2423
2424 // Test that we properly handle failures to add a send stream.
TEST_F(WebRtcVoiceEngineTestFake,AddSendStreamFail)2425 TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
2426 EXPECT_TRUE(SetupEngine());
2427 voe_.set_fail_create_channel(true);
2428 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2429 }
2430
2431 // Test that AddRecvStream creates new stream.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStream)2432 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
2433 EXPECT_TRUE(SetupEngineWithRecvStream());
2434 int channel_num = voe_.GetLastChannel();
2435 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2436 EXPECT_NE(channel_num, voe_.GetLastChannel());
2437 }
2438
2439 // Test that after adding a recv stream, we do not decode more codecs than
2440 // those previously passed into SetRecvCodecs.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamUnsupportedCodec)2441 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2442 EXPECT_TRUE(SetupEngineWithSendStream());
2443 cricket::AudioRecvParameters parameters;
2444 parameters.codecs.push_back(kIsacCodec);
2445 parameters.codecs.push_back(kPcmuCodec);
2446 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2447 EXPECT_TRUE(channel_->AddRecvStream(
2448 cricket::StreamParams::CreateLegacy(kSsrc1)));
2449 int channel_num2 = voe_.GetLastChannel();
2450 webrtc::CodecInst gcodec;
2451 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
2452 gcodec.plfreq = 48000;
2453 gcodec.channels = 2;
2454 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2455 }
2456
2457 // Test that we properly clean up any streams that were added, even if
2458 // not explicitly removed.
TEST_F(WebRtcVoiceEngineTestFake,StreamCleanup)2459 TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2460 EXPECT_TRUE(SetupEngineWithSendStream());
2461 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2462 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2463 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2464 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2465 delete channel_;
2466 channel_ = NULL;
2467 EXPECT_EQ(0, voe_.GetNumChannels());
2468 }
2469
TEST_F(WebRtcVoiceEngineTestFake,TestAddRecvStreamFailWithZeroSsrc)2470 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2471 EXPECT_TRUE(SetupEngineWithSendStream());
2472 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2473 }
2474
TEST_F(WebRtcVoiceEngineTestFake,TestNoLeakingWhenAddRecvStreamFail)2475 TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2476 EXPECT_TRUE(SetupEngine());
2477 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2478 // Manually delete channel to simulate a failure.
2479 int channel = voe_.GetLastChannel();
2480 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2481 // Add recv stream 2 should work.
2482 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2483 int new_channel = voe_.GetLastChannel();
2484 EXPECT_NE(channel, new_channel);
2485 // The last created channel is deleted too.
2486 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
2487 }
2488
2489 // Test the InsertDtmf on default send stream as caller.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnDefaultSendStreamAsCaller)2490 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2491 TestInsertDtmf(0, true);
2492 }
2493
2494 // Test the InsertDtmf on default send stream as callee
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnDefaultSendStreamAsCallee)2495 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2496 TestInsertDtmf(0, false);
2497 }
2498
2499 // Test the InsertDtmf on specified send stream as caller.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnSendStreamAsCaller)2500 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2501 TestInsertDtmf(kSsrc1, true);
2502 }
2503
2504 // Test the InsertDtmf on specified send stream as callee.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnSendStreamAsCallee)2505 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2506 TestInsertDtmf(kSsrc1, false);
2507 }
2508
TEST_F(WebRtcVoiceEngineTestFake,TestSetPlayoutError)2509 TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2510 EXPECT_TRUE(SetupEngineWithSendStream());
2511 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2512 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2513 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2514 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2515 EXPECT_TRUE(channel_->SetPlayout(true));
2516 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2517 EXPECT_TRUE(channel_->SetPlayout(false));
2518 EXPECT_FALSE(channel_->SetPlayout(true));
2519 }
2520
TEST_F(WebRtcVoiceEngineTestFake,SetAudioOptions)2521 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2522 EXPECT_TRUE(SetupEngineWithSendStream());
2523
2524 bool ec_enabled;
2525 webrtc::EcModes ec_mode;
2526 webrtc::AecmModes aecm_mode;
2527 bool cng_enabled;
2528 bool agc_enabled;
2529 webrtc::AgcModes agc_mode;
2530 webrtc::AgcConfig agc_config;
2531 bool ns_enabled;
2532 webrtc::NsModes ns_mode;
2533 bool highpass_filter_enabled;
2534 bool stereo_swapping_enabled;
2535 bool typing_detection_enabled;
2536 voe_.GetEcStatus(ec_enabled, ec_mode);
2537 voe_.GetAecmMode(aecm_mode, cng_enabled);
2538 voe_.GetAgcStatus(agc_enabled, agc_mode);
2539 voe_.GetAgcConfig(agc_config);
2540 voe_.GetNsStatus(ns_enabled, ns_mode);
2541 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2542 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2543 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2544 EXPECT_TRUE(ec_enabled);
2545 EXPECT_TRUE(voe_.ec_metrics_enabled());
2546 EXPECT_FALSE(cng_enabled);
2547 EXPECT_TRUE(agc_enabled);
2548 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2549 EXPECT_TRUE(ns_enabled);
2550 EXPECT_TRUE(highpass_filter_enabled);
2551 EXPECT_FALSE(stereo_swapping_enabled);
2552 EXPECT_TRUE(typing_detection_enabled);
2553 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2554 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2555 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2556 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2557
2558 // Nothing set in AudioOptions, so everything should be as default.
2559 send_parameters_.options = cricket::AudioOptions();
2560 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2561 voe_.GetEcStatus(ec_enabled, ec_mode);
2562 voe_.GetAecmMode(aecm_mode, cng_enabled);
2563 voe_.GetAgcStatus(agc_enabled, agc_mode);
2564 voe_.GetAgcConfig(agc_config);
2565 voe_.GetNsStatus(ns_enabled, ns_mode);
2566 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2567 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2568 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2569 EXPECT_TRUE(ec_enabled);
2570 EXPECT_TRUE(voe_.ec_metrics_enabled());
2571 EXPECT_FALSE(cng_enabled);
2572 EXPECT_TRUE(agc_enabled);
2573 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2574 EXPECT_TRUE(ns_enabled);
2575 EXPECT_TRUE(highpass_filter_enabled);
2576 EXPECT_FALSE(stereo_swapping_enabled);
2577 EXPECT_TRUE(typing_detection_enabled);
2578 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2579 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2580 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2581 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2582
2583 // Turn echo cancellation off
2584 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2585 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2586 voe_.GetEcStatus(ec_enabled, ec_mode);
2587 EXPECT_FALSE(ec_enabled);
2588
2589 // Turn echo cancellation back on, with settings, and make sure
2590 // nothing else changed.
2591 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
2592 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2593 voe_.GetEcStatus(ec_enabled, ec_mode);
2594 voe_.GetAecmMode(aecm_mode, cng_enabled);
2595 voe_.GetAgcStatus(agc_enabled, agc_mode);
2596 voe_.GetAgcConfig(agc_config);
2597 voe_.GetNsStatus(ns_enabled, ns_mode);
2598 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2599 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2600 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2601 EXPECT_TRUE(ec_enabled);
2602 EXPECT_TRUE(voe_.ec_metrics_enabled());
2603 EXPECT_TRUE(agc_enabled);
2604 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2605 EXPECT_TRUE(ns_enabled);
2606 EXPECT_TRUE(highpass_filter_enabled);
2607 EXPECT_FALSE(stereo_swapping_enabled);
2608 EXPECT_TRUE(typing_detection_enabled);
2609 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2610 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2611
2612 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2613 // control.
2614 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2615 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2616 voe_.GetEcStatus(ec_enabled, ec_mode);
2617 voe_.GetAecmMode(aecm_mode, cng_enabled);
2618 EXPECT_TRUE(ec_enabled);
2619 EXPECT_TRUE(voe_.ec_metrics_enabled());
2620 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2621
2622 // Turn off echo cancellation and delay agnostic aec.
2623 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2624 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2625 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2626 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2627 voe_.GetEcStatus(ec_enabled, ec_mode);
2628 EXPECT_FALSE(ec_enabled);
2629 // Turning delay agnostic aec back on should also turn on echo cancellation.
2630 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2631 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2632 voe_.GetEcStatus(ec_enabled, ec_mode);
2633 EXPECT_TRUE(ec_enabled);
2634 EXPECT_TRUE(voe_.ec_metrics_enabled());
2635 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2636
2637 // Turn off AGC
2638 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
2639 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2640 voe_.GetAgcStatus(agc_enabled, agc_mode);
2641 EXPECT_FALSE(agc_enabled);
2642
2643 // Turn AGC back on
2644 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2645 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
2646 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2647 voe_.GetAgcStatus(agc_enabled, agc_mode);
2648 EXPECT_TRUE(agc_enabled);
2649 voe_.GetAgcConfig(agc_config);
2650 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2651
2652 // Turn off other options (and stereo swapping on).
2653 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2654 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2655 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2656 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
2657 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2658 voe_.GetNsStatus(ns_enabled, ns_mode);
2659 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2660 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2661 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2662 EXPECT_FALSE(ns_enabled);
2663 EXPECT_FALSE(highpass_filter_enabled);
2664 EXPECT_FALSE(typing_detection_enabled);
2665 EXPECT_TRUE(stereo_swapping_enabled);
2666
2667 // Set options again to ensure it has no impact.
2668 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2669 voe_.GetEcStatus(ec_enabled, ec_mode);
2670 voe_.GetNsStatus(ns_enabled, ns_mode);
2671 EXPECT_TRUE(ec_enabled);
2672 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2673 EXPECT_FALSE(ns_enabled);
2674 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2675 }
2676
TEST_F(WebRtcVoiceEngineTestFake,DefaultOptions)2677 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2678 EXPECT_TRUE(SetupEngineWithSendStream());
2679
2680 bool ec_enabled;
2681 webrtc::EcModes ec_mode;
2682 bool agc_enabled;
2683 webrtc::AgcModes agc_mode;
2684 bool ns_enabled;
2685 webrtc::NsModes ns_mode;
2686 bool highpass_filter_enabled;
2687 bool stereo_swapping_enabled;
2688 bool typing_detection_enabled;
2689
2690 voe_.GetEcStatus(ec_enabled, ec_mode);
2691 voe_.GetAgcStatus(agc_enabled, agc_mode);
2692 voe_.GetNsStatus(ns_enabled, ns_mode);
2693 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2694 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2695 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2696 EXPECT_TRUE(ec_enabled);
2697 EXPECT_TRUE(agc_enabled);
2698 EXPECT_TRUE(ns_enabled);
2699 EXPECT_TRUE(highpass_filter_enabled);
2700 EXPECT_TRUE(typing_detection_enabled);
2701 EXPECT_FALSE(stereo_swapping_enabled);
2702 }
2703
TEST_F(WebRtcVoiceEngineTestFake,InitDoesNotOverwriteDefaultAgcConfig)2704 TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2705 webrtc::AgcConfig set_config = {0};
2706 set_config.targetLeveldBOv = 3;
2707 set_config.digitalCompressionGaindB = 9;
2708 set_config.limiterEnable = true;
2709 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2710 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2711
2712 webrtc::AgcConfig config = {0};
2713 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2714 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2715 EXPECT_EQ(set_config.digitalCompressionGaindB,
2716 config.digitalCompressionGaindB);
2717 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2718 }
2719
TEST_F(WebRtcVoiceEngineTestFake,SetOptionOverridesViaChannels)2720 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2721 EXPECT_TRUE(SetupEngineWithSendStream());
2722 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
2723 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2724 engine_.CreateChannel(&call_, cricket::AudioOptions())));
2725 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
2726 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2727 engine_.CreateChannel(&call_, cricket::AudioOptions())));
2728
2729 // Have to add a stream to make SetSend work.
2730 cricket::StreamParams stream1;
2731 stream1.ssrcs.push_back(1);
2732 channel1->AddSendStream(stream1);
2733 cricket::StreamParams stream2;
2734 stream2.ssrcs.push_back(2);
2735 channel2->AddSendStream(stream2);
2736
2737 // AEC and AGC and NS
2738 cricket::AudioSendParameters parameters_options_all = send_parameters_;
2739 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2740 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2741 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
2742 ASSERT_TRUE(channel1->SetSendParameters(parameters_options_all));
2743 EXPECT_EQ(parameters_options_all.options, channel1->options());
2744 ASSERT_TRUE(channel2->SetSendParameters(parameters_options_all));
2745 EXPECT_EQ(parameters_options_all.options, channel2->options());
2746
2747 // unset NS
2748 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
2749 parameters_options_no_ns.options.noise_suppression =
2750 rtc::Optional<bool>(false);
2751 ASSERT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
2752 cricket::AudioOptions expected_options = parameters_options_all.options;
2753 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2754 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2755 expected_options.noise_suppression = rtc::Optional<bool>(false);
2756 EXPECT_EQ(expected_options, channel1->options());
2757
2758 // unset AGC
2759 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
2760 parameters_options_no_agc.options.auto_gain_control =
2761 rtc::Optional<bool>(false);
2762 ASSERT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
2763 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2764 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2765 expected_options.noise_suppression = rtc::Optional<bool>(true);
2766 EXPECT_EQ(expected_options, channel2->options());
2767
2768 ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2769 bool ec_enabled;
2770 webrtc::EcModes ec_mode;
2771 bool agc_enabled;
2772 webrtc::AgcModes agc_mode;
2773 bool ns_enabled;
2774 webrtc::NsModes ns_mode;
2775 voe_.GetEcStatus(ec_enabled, ec_mode);
2776 voe_.GetAgcStatus(agc_enabled, agc_mode);
2777 voe_.GetNsStatus(ns_enabled, ns_mode);
2778 EXPECT_TRUE(ec_enabled);
2779 EXPECT_TRUE(agc_enabled);
2780 EXPECT_TRUE(ns_enabled);
2781
2782 channel1->SetSend(cricket::SEND_MICROPHONE);
2783 voe_.GetEcStatus(ec_enabled, ec_mode);
2784 voe_.GetAgcStatus(agc_enabled, agc_mode);
2785 voe_.GetNsStatus(ns_enabled, ns_mode);
2786 EXPECT_TRUE(ec_enabled);
2787 EXPECT_TRUE(agc_enabled);
2788 EXPECT_FALSE(ns_enabled);
2789
2790 channel2->SetSend(cricket::SEND_MICROPHONE);
2791 voe_.GetEcStatus(ec_enabled, ec_mode);
2792 voe_.GetAgcStatus(agc_enabled, agc_mode);
2793 voe_.GetNsStatus(ns_enabled, ns_mode);
2794 EXPECT_TRUE(ec_enabled);
2795 EXPECT_FALSE(agc_enabled);
2796 EXPECT_TRUE(ns_enabled);
2797
2798 // Make sure settings take effect while we are sending.
2799 ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2800 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2801 send_parameters_;
2802 parameters_options_no_agc_nor_ns.options.auto_gain_control =
2803 rtc::Optional<bool>(false);
2804 parameters_options_no_agc_nor_ns.options.noise_suppression =
2805 rtc::Optional<bool>(false);
2806 channel2->SetSend(cricket::SEND_MICROPHONE);
2807 channel2->SetSendParameters(parameters_options_no_agc_nor_ns);
2808 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2809 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2810 expected_options.noise_suppression = rtc::Optional<bool>(false);
2811 EXPECT_EQ(expected_options, channel2->options());
2812 voe_.GetEcStatus(ec_enabled, ec_mode);
2813 voe_.GetAgcStatus(agc_enabled, agc_mode);
2814 voe_.GetNsStatus(ns_enabled, ns_mode);
2815 EXPECT_TRUE(ec_enabled);
2816 EXPECT_FALSE(agc_enabled);
2817 EXPECT_FALSE(ns_enabled);
2818 }
2819
2820 // This test verifies DSCP settings are properly applied on voice media channel.
TEST_F(WebRtcVoiceEngineTestFake,TestSetDscpOptions)2821 TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2822 EXPECT_TRUE(SetupEngineWithSendStream());
2823 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
2824 engine_.CreateChannel(&call_, cricket::AudioOptions()));
2825 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2826 new cricket::FakeNetworkInterface);
2827 channel->SetInterface(network_interface.get());
2828 cricket::AudioSendParameters parameters = send_parameters_;
2829 parameters.options.dscp = rtc::Optional<bool>(true);
2830 EXPECT_TRUE(channel->SetSendParameters(parameters));
2831 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2832 // Verify previous value is not modified if dscp option is not set.
2833 EXPECT_TRUE(channel->SetSendParameters(send_parameters_));
2834 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2835 parameters.options.dscp = rtc::Optional<bool>(false);
2836 EXPECT_TRUE(channel->SetSendParameters(parameters));
2837 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2838 }
2839
TEST_F(WebRtcVoiceEngineTestFake,TestGetReceiveChannelId)2840 TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
2841 EXPECT_TRUE(SetupEngine());
2842 cricket::WebRtcVoiceMediaChannel* media_channel =
2843 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2844 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
2845 EXPECT_TRUE(channel_->AddRecvStream(
2846 cricket::StreamParams::CreateLegacy(kSsrc1)));
2847 int channel_id = voe_.GetLastChannel();
2848 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
2849 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
2850 EXPECT_TRUE(channel_->AddRecvStream(
2851 cricket::StreamParams::CreateLegacy(kSsrc2)));
2852 int channel_id2 = voe_.GetLastChannel();
2853 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
2854 }
2855
TEST_F(WebRtcVoiceEngineTestFake,TestGetSendChannelId)2856 TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
2857 EXPECT_TRUE(SetupEngine());
2858 cricket::WebRtcVoiceMediaChannel* media_channel =
2859 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2860 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2861 EXPECT_TRUE(channel_->AddSendStream(
2862 cricket::StreamParams::CreateLegacy(kSsrc1)));
2863 int channel_id = voe_.GetLastChannel();
2864 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
2865 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
2866 EXPECT_TRUE(channel_->AddSendStream(
2867 cricket::StreamParams::CreateLegacy(kSsrc2)));
2868 int channel_id2 = voe_.GetLastChannel();
2869 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
2870 }
2871
TEST_F(WebRtcVoiceEngineTestFake,SetOutputVolume)2872 TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
2873 EXPECT_TRUE(SetupEngine());
2874 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
2875 cricket::StreamParams stream;
2876 stream.ssrcs.push_back(kSsrc2);
2877 EXPECT_TRUE(channel_->AddRecvStream(stream));
2878 int channel_id = voe_.GetLastChannel();
2879 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
2880 float scale = 0;
2881 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2882 EXPECT_DOUBLE_EQ(3, scale);
2883 }
2884
TEST_F(WebRtcVoiceEngineTestFake,SetOutputVolumeDefaultRecvStream)2885 TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
2886 EXPECT_TRUE(SetupEngine());
2887 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
2888 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2889 int channel_id = voe_.GetLastChannel();
2890 float scale = 0;
2891 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2892 EXPECT_DOUBLE_EQ(2, scale);
2893 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
2894 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2895 EXPECT_DOUBLE_EQ(3, scale);
2896 }
2897
TEST_F(WebRtcVoiceEngineTestFake,SetsSyncGroupFromSyncLabel)2898 TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
2899 const uint32_t kAudioSsrc = 123;
2900 const std::string kSyncLabel = "AvSyncLabel";
2901
2902 EXPECT_TRUE(SetupEngineWithSendStream());
2903 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
2904 sp.sync_label = kSyncLabel;
2905 // Creating two channels to make sure that sync label is set properly for both
2906 // the default voice channel and following ones.
2907 EXPECT_TRUE(channel_->AddRecvStream(sp));
2908 sp.ssrcs[0] += 1;
2909 EXPECT_TRUE(channel_->AddRecvStream(sp));
2910
2911 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
2912 EXPECT_EQ(kSyncLabel,
2913 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
2914 << "SyncGroup should be set based on sync_label";
2915 EXPECT_EQ(kSyncLabel,
2916 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
2917 << "SyncGroup should be set based on sync_label";
2918 }
2919
TEST_F(WebRtcVoiceEngineTestFake,CanChangeCombinedBweOption)2920 TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
2921 // Test that changing the combined_audio_video_bwe option results in the
2922 // expected state changes on an associated Call.
2923 std::vector<uint32_t> ssrcs;
2924 ssrcs.push_back(223);
2925 ssrcs.push_back(224);
2926
2927 EXPECT_TRUE(SetupEngineWithSendStream());
2928 cricket::WebRtcVoiceMediaChannel* media_channel =
2929 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2930 for (uint32_t ssrc : ssrcs) {
2931 EXPECT_TRUE(media_channel->AddRecvStream(
2932 cricket::StreamParams::CreateLegacy(ssrc)));
2933 }
2934 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2935
2936 // Combined BWE should be disabled.
2937 for (uint32_t ssrc : ssrcs) {
2938 const auto* s = call_.GetAudioReceiveStream(ssrc);
2939 EXPECT_NE(nullptr, s);
2940 EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2941 }
2942
2943 // Enable combined BWE option - now it should be set up.
2944 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2945 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2946 for (uint32_t ssrc : ssrcs) {
2947 const auto* s = call_.GetAudioReceiveStream(ssrc);
2948 EXPECT_NE(nullptr, s);
2949 EXPECT_EQ(true, s->GetConfig().combined_audio_video_bwe);
2950 }
2951
2952 // Disable combined BWE option - should be disabled again.
2953 send_parameters_.options.combined_audio_video_bwe =
2954 rtc::Optional<bool>(false);
2955 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2956 for (uint32_t ssrc : ssrcs) {
2957 const auto* s = call_.GetAudioReceiveStream(ssrc);
2958 EXPECT_NE(nullptr, s);
2959 EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2960 }
2961
2962 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2963 }
2964
TEST_F(WebRtcVoiceEngineTestFake,ConfigureCombinedBweForNewRecvStreams)2965 TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
2966 // Test that adding receive streams after enabling combined bandwidth
2967 // estimation will correctly configure each channel.
2968 EXPECT_TRUE(SetupEngineWithSendStream());
2969 cricket::WebRtcVoiceMediaChannel* media_channel =
2970 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2971 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2972 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2973
2974 for (uint32_t ssrc : kSsrcs4) {
2975 EXPECT_TRUE(media_channel->AddRecvStream(
2976 cricket::StreamParams::CreateLegacy(ssrc)));
2977 EXPECT_NE(nullptr, call_.GetAudioReceiveStream(ssrc));
2978 }
2979 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioReceiveStreams().size());
2980 }
2981
2982 // TODO(solenberg): Remove, once recv streams are configured through Call.
2983 // (This is then covered by TestSetRecvRtpHeaderExtensions.)
TEST_F(WebRtcVoiceEngineTestFake,ConfiguresAudioReceiveStreamRtpExtensions)2984 TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
2985 // Test that setting the header extensions results in the expected state
2986 // changes on an associated Call.
2987 std::vector<uint32_t> ssrcs;
2988 ssrcs.push_back(223);
2989 ssrcs.push_back(224);
2990
2991 EXPECT_TRUE(SetupEngineWithSendStream());
2992 cricket::WebRtcVoiceMediaChannel* media_channel =
2993 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2994 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2995 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2996 for (uint32_t ssrc : ssrcs) {
2997 EXPECT_TRUE(media_channel->AddRecvStream(
2998 cricket::StreamParams::CreateLegacy(ssrc)));
2999 }
3000
3001 // Combined BWE should be set up, but with no configured extensions.
3002 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3003 for (uint32_t ssrc : ssrcs) {
3004 const auto* s = call_.GetAudioReceiveStream(ssrc);
3005 EXPECT_NE(nullptr, s);
3006 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3007 }
3008
3009 // Set up receive extensions.
3010 cricket::RtpCapabilities capabilities = engine_.GetCapabilities();
3011 cricket::AudioRecvParameters recv_parameters;
3012 recv_parameters.extensions = capabilities.header_extensions;
3013 channel_->SetRecvParameters(recv_parameters);
3014 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3015 for (uint32_t ssrc : ssrcs) {
3016 const auto* s = call_.GetAudioReceiveStream(ssrc);
3017 EXPECT_NE(nullptr, s);
3018 const auto& s_exts = s->GetConfig().rtp.extensions;
3019 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3020 for (const auto& e_ext : capabilities.header_extensions) {
3021 for (const auto& s_ext : s_exts) {
3022 if (e_ext.id == s_ext.id) {
3023 EXPECT_EQ(e_ext.uri, s_ext.name);
3024 }
3025 }
3026 }
3027 }
3028
3029 // Disable receive extensions.
3030 channel_->SetRecvParameters(cricket::AudioRecvParameters());
3031 for (uint32_t ssrc : ssrcs) {
3032 const auto* s = call_.GetAudioReceiveStream(ssrc);
3033 EXPECT_NE(nullptr, s);
3034 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3035 }
3036 }
3037
TEST_F(WebRtcVoiceEngineTestFake,DeliverAudioPacket_Call)3038 TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3039 // Test that packets are forwarded to the Call when configured accordingly.
3040 const uint32_t kAudioSsrc = 1;
3041 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3042 static const unsigned char kRtcp[] = {
3043 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3044 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3046 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3047 };
3048 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3049
3050 EXPECT_TRUE(SetupEngineWithSendStream());
3051 cricket::WebRtcVoiceMediaChannel* media_channel =
3052 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3053 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
3054 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3055 EXPECT_TRUE(media_channel->AddRecvStream(
3056 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3057
3058 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
3059 const cricket::FakeAudioReceiveStream* s =
3060 call_.GetAudioReceiveStream(kAudioSsrc);
3061 EXPECT_EQ(0, s->received_packets());
3062 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3063 EXPECT_EQ(1, s->received_packets());
3064 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3065 EXPECT_EQ(2, s->received_packets());
3066 }
3067
3068 // All receive channels should be associated with the first send channel,
3069 // since they do not send RTCP SR.
TEST_F(WebRtcVoiceEngineTestFake,AssociateFirstSendChannel)3070 TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel) {
3071 EXPECT_TRUE(SetupEngineWithSendStream());
3072 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3073 int default_channel = voe_.GetLastChannel();
3074 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3075 int recv_ch = voe_.GetLastChannel();
3076 EXPECT_NE(recv_ch, default_channel);
3077 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3078 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3079 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3080 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
3081 recv_ch = voe_.GetLastChannel();
3082 EXPECT_NE(recv_ch, default_channel);
3083 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3084 }
3085
TEST_F(WebRtcVoiceEngineTestFake,AssociateChannelResetUponDeleteChannnel)3086 TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3087 EXPECT_TRUE(SetupEngineWithSendStream());
3088 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3089
3090 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3091 int recv_ch = voe_.GetLastChannel();
3092
3093 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3094 int send_ch = voe_.GetLastChannel();
3095
3096 // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3097 // deleting logic, i.e., deleting |send_ch| will reset the associate send
3098 // channel of |recv_ch|.This is not a common case, since, normally, only the
3099 // default channel can be associated. However, the default is not deletable.
3100 // So we force the |recv_ch| to associate with a non-default channel.
3101 EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3102 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3103
3104 EXPECT_TRUE(channel_->RemoveSendStream(2));
3105 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3106 }
3107
3108 // Tests that the library initializes and shuts down properly.
TEST(WebRtcVoiceEngineTest,StartupShutdown)3109 TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3110 cricket::WebRtcVoiceEngine engine;
3111 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3112 rtc::scoped_ptr<webrtc::Call> call(
3113 webrtc::Call::Create(webrtc::Call::Config()));
3114 cricket::VoiceMediaChannel* channel =
3115 engine.CreateChannel(call.get(), cricket::AudioOptions());
3116 EXPECT_TRUE(channel != nullptr);
3117 delete channel;
3118 engine.Terminate();
3119
3120 // Reinit to catch regression where VoiceEngineObserver reference is lost
3121 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3122 engine.Terminate();
3123 }
3124
3125 // Tests that the library is configured with the codecs we want.
TEST(WebRtcVoiceEngineTest,HasCorrectCodecs)3126 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3127 // Check codecs by name.
3128 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3129 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0), nullptr));
3130 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3131 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0), nullptr));
3132 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3133 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0), nullptr));
3134 // Check that name matching is case-insensitive.
3135 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3136 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0), nullptr));
3137 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3138 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0), nullptr));
3139 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3140 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0), nullptr));
3141 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3142 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0), nullptr));
3143 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3144 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0), nullptr));
3145 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3146 cricket::AudioCodec(96, "red", 8000, 0, 1, 0), nullptr));
3147 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3148 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0), nullptr));
3149 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3150 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0), nullptr));
3151 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3152 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0), nullptr));
3153 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3154 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0), nullptr));
3155 // Check codecs with an id by id.
3156 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3157 cricket::AudioCodec(0, "", 8000, 0, 1, 0), nullptr)); // PCMU
3158 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3159 cricket::AudioCodec(8, "", 8000, 0, 1, 0), nullptr)); // PCMA
3160 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3161 cricket::AudioCodec(9, "", 8000, 0, 1, 0), nullptr)); // G722
3162 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3163 cricket::AudioCodec(13, "", 8000, 0, 1, 0), nullptr)); // CN
3164 // Check sample/bitrate matching.
3165 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3166 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0), nullptr));
3167 // Check that bad codecs fail.
3168 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3169 cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0), nullptr));
3170 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3171 cricket::AudioCodec(88, "", 0, 0, 1, 0), nullptr));
3172 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3173 cricket::AudioCodec(0, "", 0, 0, 2, 0), nullptr));
3174 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3175 cricket::AudioCodec(0, "", 5000, 0, 1, 0), nullptr));
3176 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3177 cricket::AudioCodec(0, "", 0, 5000, 1, 0), nullptr));
3178
3179 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3180 cricket::WebRtcVoiceEngine engine;
3181 for (std::vector<cricket::AudioCodec>::const_iterator it =
3182 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3183 if (it->name == "CN" && it->clockrate == 16000) {
3184 EXPECT_EQ(105, it->id);
3185 } else if (it->name == "CN" && it->clockrate == 32000) {
3186 EXPECT_EQ(106, it->id);
3187 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3188 EXPECT_EQ(103, it->id);
3189 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3190 EXPECT_EQ(104, it->id);
3191 } else if (it->name == "G722" && it->clockrate == 8000) {
3192 EXPECT_EQ(9, it->id);
3193 } else if (it->name == "telephone-event") {
3194 EXPECT_EQ(126, it->id);
3195 } else if (it->name == "red") {
3196 EXPECT_EQ(127, it->id);
3197 } else if (it->name == "opus") {
3198 EXPECT_EQ(111, it->id);
3199 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3200 EXPECT_EQ("10", it->params.find("minptime")->second);
3201 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3202 EXPECT_EQ("60", it->params.find("maxptime")->second);
3203 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3204 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
3205 }
3206 }
3207 engine.Terminate();
3208 }
3209
3210 // Tests that VoE supports at least 32 channels
TEST(WebRtcVoiceEngineTest,Has32Channels)3211 TEST(WebRtcVoiceEngineTest, Has32Channels) {
3212 cricket::WebRtcVoiceEngine engine;
3213 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3214 rtc::scoped_ptr<webrtc::Call> call(
3215 webrtc::Call::Create(webrtc::Call::Config()));
3216
3217 cricket::VoiceMediaChannel* channels[32];
3218 int num_channels = 0;
3219 while (num_channels < arraysize(channels)) {
3220 cricket::VoiceMediaChannel* channel =
3221 engine.CreateChannel(call.get(), cricket::AudioOptions());
3222 if (!channel)
3223 break;
3224 channels[num_channels++] = channel;
3225 }
3226
3227 int expected = arraysize(channels);
3228 EXPECT_EQ(expected, num_channels);
3229
3230 while (num_channels > 0) {
3231 delete channels[--num_channels];
3232 }
3233 engine.Terminate();
3234 }
3235
3236 // Test that we set our preferred codecs properly.
TEST(WebRtcVoiceEngineTest,SetRecvCodecs)3237 TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3238 cricket::WebRtcVoiceEngine engine;
3239 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3240 rtc::scoped_ptr<webrtc::Call> call(
3241 webrtc::Call::Create(webrtc::Call::Config()));
3242 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::AudioOptions(),
3243 call.get());
3244 cricket::AudioRecvParameters parameters;
3245 parameters.codecs = engine.codecs();
3246 EXPECT_TRUE(channel.SetRecvParameters(parameters));
3247 }
3248