3 * Copyright 2008 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
29 #include "talk/base/win32.h"
33 #include "talk/base/byteorder.h"
34 #include "talk/base/gunit.h"
35 #include "talk/media/base/constants.h"
36 #include "talk/media/base/fakemediaengine.h"
37 #include "talk/media/base/fakemediaprocessor.h"
38 #include "talk/media/base/fakenetworkinterface.h"
39 #include "talk/media/base/fakertp.h"
40 #include "talk/media/webrtc/fakewebrtcvoiceengine.h"
41 #include "talk/media/webrtc/webrtcvoiceengine.h"
42 #include "talk/p2p/base/fakesession.h"
43 #include "talk/session/media/channel.h"
45 // Tests for the WebRtcVoiceEngine/VoiceChannel code.
47 using cricket::kRtpAudioLevelHeaderExtension;
48 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
50 static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
51 static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
52 static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
53 static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
54 static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
55 static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
56 static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
57 static const cricket::AudioCodec
58 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
59 static const cricket::AudioCodec* const kAudioCodecs[] = {
60 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
61 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
63 const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
64 static uint32 kSsrc1 = 0x99;
65 static uint32 kSsrc2 = 0x98;
67 class FakeVoEWrapper : public cricket::VoEWrapper {
69 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
70 : cricket::VoEWrapper(engine, // processing
85 class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
87 virtual int SetTraceFilter(const unsigned int filter) {
91 virtual int SetTraceFile(const char* fileNameUTF8) {
94 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
100 class WebRtcVoiceEngineTestFake : public testing::Test {
102 class ChannelErrorListener : public sigslot::has_slots<> {
104 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
105 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
106 ASSERT(channel != NULL);
107 channel->SignalMediaError.connect(
108 this, &ChannelErrorListener::OnVoiceChannelError);
110 void OnVoiceChannelError(uint32 ssrc,
111 cricket::VoiceMediaChannel::Error error) {
117 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
119 uint32 ssrc() const {
122 cricket::VoiceMediaChannel::Error error() const {
128 cricket::VoiceMediaChannel::Error error_;
131 WebRtcVoiceEngineTestFake()
132 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
133 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
134 trace_wrapper_(new FakeVoETraceWrapper()),
135 engine_(new FakeVoEWrapper(&voe_),
136 new FakeVoEWrapper(&voe_sc_),
138 channel_(NULL), soundclip_(NULL) {
139 options_conference_.conference_mode.Set(true);
140 options_adjust_agc_.adjust_agc_delta.Set(-10);
142 bool SetupEngineWithoutStream() {
143 if (!engine_.Init(talk_base::Thread::Current())) {
146 channel_ = engine_.CreateChannel();
147 return (channel_ != NULL);
150 if (!SetupEngineWithoutStream()) {
153 return channel_->AddSendStream(
154 cricket::StreamParams::CreateLegacy(kSsrc1));
156 void SetupForMultiSendStream() {
157 EXPECT_TRUE(SetupEngine());
158 // Remove stream added in Setup, which is corresponding to default channel.
159 int default_channel_num = voe_.GetLastChannel();
160 uint32 default_send_ssrc = 0u;
161 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
162 EXPECT_EQ(kSsrc1, default_send_ssrc);
163 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
165 // Verify the default channel still exists.
166 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
168 void DeliverPacket(const void* data, int len) {
169 talk_base::Buffer packet(data, len);
170 channel_->OnPacketReceived(&packet, talk_base::PacketTime());
172 virtual void TearDown() {
178 void TestInsertDtmf(uint32 ssrc, bool caller) {
179 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
180 channel_ = engine_.CreateChannel();
181 EXPECT_TRUE(channel_ != NULL);
183 // if this is a caller, local description will be applied and add the
185 EXPECT_TRUE(channel_->AddSendStream(
186 cricket::StreamParams::CreateLegacy(kSsrc1)));
188 int channel_id = voe_.GetLastChannel();
190 // Test we can only InsertDtmf when the other side supports telephone-event.
191 std::vector<cricket::AudioCodec> codecs;
192 codecs.push_back(kPcmuCodec);
193 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
194 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
195 EXPECT_FALSE(channel_->CanInsertDtmf());
196 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
197 codecs.push_back(kTelephoneEventCodec);
198 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
199 EXPECT_TRUE(channel_->CanInsertDtmf());
202 // There's no active send channel yet.
203 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
204 EXPECT_TRUE(channel_->AddSendStream(
205 cricket::StreamParams::CreateLegacy(kSsrc1)));
208 // Check we fail if the ssrc is invalid.
209 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
212 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
213 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
214 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
217 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
218 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
219 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
221 // Test send and play
222 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
223 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
224 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
225 cricket::DF_PLAY | cricket::DF_SEND));
226 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
227 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
230 // Test that send bandwidth is set correctly.
231 // |codec| is the codec under test.
232 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
233 // |expected_result| is the expected result from SetMaxSendBandwidth().
234 // |expected_bitrate| is the expected audio bitrate afterward.
235 void TestSendBandwidth(const cricket::AudioCodec& codec,
237 bool expected_result,
238 int expected_bitrate) {
239 int channel_num = voe_.GetLastChannel();
240 std::vector<cricket::AudioCodec> codecs;
242 codecs.push_back(codec);
243 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
245 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
246 EXPECT_EQ(expected_result, result);
248 webrtc::CodecInst temp_codec;
249 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
251 EXPECT_EQ(expected_bitrate, temp_codec.rate);
254 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
255 EXPECT_TRUE(SetupEngineWithoutStream());
256 int channel_num = voe_.GetLastChannel();
258 // Ensure extensions are off by default.
259 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
261 std::vector<cricket::RtpHeaderExtension> extensions;
262 // Ensure unknown extensions won't cause an error.
263 extensions.push_back(cricket::RtpHeaderExtension(
264 "urn:ietf:params:unknownextention", 1));
265 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
266 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
268 // Ensure extensions stay off with an empty list of headers.
270 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
271 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
273 // Ensure extension is set properly.
275 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
276 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
277 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
279 // Ensure extension is set properly on new channel.
280 // The first stream to occupy the default channel.
281 EXPECT_TRUE(channel_->AddSendStream(
282 cricket::StreamParams::CreateLegacy(123)));
283 EXPECT_TRUE(channel_->AddSendStream(
284 cricket::StreamParams::CreateLegacy(234)));
285 int new_channel_num = voe_.GetLastChannel();
286 EXPECT_NE(channel_num, new_channel_num);
287 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
289 // Ensure all extensions go back off with an empty list.
291 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
292 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
293 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
296 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
297 EXPECT_TRUE(SetupEngineWithoutStream());
298 int channel_num = voe_.GetLastChannel();
300 // Ensure extensions are off by default.
301 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
303 std::vector<cricket::RtpHeaderExtension> extensions;
304 // Ensure unknown extensions won't cause an error.
305 extensions.push_back(cricket::RtpHeaderExtension(
306 "urn:ietf:params:unknownextention", 1));
307 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
308 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
310 // Ensure extensions stay off with an empty list of headers.
312 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
313 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
315 // Ensure extension is set properly.
317 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
318 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
319 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
321 // Ensure extension is set properly on new channel.
322 // The first stream to occupy the default channel.
323 EXPECT_TRUE(channel_->AddRecvStream(
324 cricket::StreamParams::CreateLegacy(345)));
325 EXPECT_TRUE(channel_->AddRecvStream(
326 cricket::StreamParams::CreateLegacy(456)));
327 int new_channel_num = voe_.GetLastChannel();
328 EXPECT_NE(channel_num, new_channel_num);
329 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
331 // Ensure all extensions go back off with an empty list.
333 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
334 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
335 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
339 cricket::FakeWebRtcVoiceEngine voe_;
340 cricket::FakeWebRtcVoiceEngine voe_sc_;
341 FakeVoETraceWrapper* trace_wrapper_;
342 cricket::WebRtcVoiceEngine engine_;
343 cricket::VoiceMediaChannel* channel_;
344 cricket::SoundclipMedia* soundclip_;
346 cricket::AudioOptions options_conference_;
347 cricket::AudioOptions options_adjust_agc_;
350 // Tests that our stub library "works".
351 TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
352 EXPECT_FALSE(voe_.IsInited());
353 EXPECT_FALSE(voe_sc_.IsInited());
354 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
355 EXPECT_TRUE(voe_.IsInited());
356 // The soundclip engine is lazily initialized.
357 EXPECT_FALSE(voe_sc_.IsInited());
359 EXPECT_FALSE(voe_.IsInited());
360 EXPECT_FALSE(voe_sc_.IsInited());
363 // Tests that we can create and destroy a channel.
364 TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
365 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
366 channel_ = engine_.CreateChannel();
367 EXPECT_TRUE(channel_ != NULL);
370 // Tests that we properly handle failures in CreateChannel.
371 TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
372 voe_.set_fail_create_channel(true);
373 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
374 channel_ = engine_.CreateChannel();
375 EXPECT_TRUE(channel_ == NULL);
378 // Tests that the list of supported codecs is created properly and ordered
380 TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
381 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
382 ASSERT_FALSE(codecs.empty());
383 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
384 EXPECT_EQ(48000, codecs[0].clockrate);
385 EXPECT_EQ(2, codecs[0].channels);
386 EXPECT_EQ(64000, codecs[0].bitrate);
387 int pref = codecs[0].preference;
388 for (size_t i = 1; i < codecs.size(); ++i) {
389 EXPECT_GT(pref, codecs[i].preference);
390 pref = codecs[i].preference;
394 // Tests that we can find codecs by name or id, and that we interpret the
395 // clockrate and bitrate fields properly.
396 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
397 cricket::AudioCodec codec;
398 webrtc::CodecInst codec_inst;
399 // Find PCMU with explicit clockrate and bitrate.
400 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
401 // Find ISAC with explicit clockrate and 0 bitrate.
402 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
403 // Find telephone-event with explicit clockrate and 0 bitrate.
404 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
405 // Find ISAC with a different payload id.
408 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
409 EXPECT_EQ(codec.id, codec_inst.pltype);
410 // Find PCMU with a 0 clockrate.
413 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
414 EXPECT_EQ(codec.id, codec_inst.pltype);
415 EXPECT_EQ(8000, codec_inst.plfreq);
416 // Find PCMU with a 0 bitrate.
419 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
420 EXPECT_EQ(codec.id, codec_inst.pltype);
421 EXPECT_EQ(64000, codec_inst.rate);
422 // Find ISAC with an explicit bitrate.
424 codec.bitrate = 32000;
425 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
426 EXPECT_EQ(codec.id, codec_inst.pltype);
427 EXPECT_EQ(32000, codec_inst.rate);
430 // Test that we set our inbound codecs properly, including changing PT.
431 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
432 EXPECT_TRUE(SetupEngine());
433 int channel_num = voe_.GetLastChannel();
434 std::vector<cricket::AudioCodec> codecs;
435 codecs.push_back(kIsacCodec);
436 codecs.push_back(kPcmuCodec);
437 codecs.push_back(kTelephoneEventCodec);
438 codecs[0].id = 106; // collide with existing telephone-event
440 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
441 webrtc::CodecInst gcodec;
442 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
443 gcodec.plfreq = 16000;
445 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
446 EXPECT_EQ(106, gcodec.pltype);
447 EXPECT_STREQ("ISAC", gcodec.plname);
448 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
450 gcodec.plfreq = 8000;
451 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
452 EXPECT_EQ(126, gcodec.pltype);
453 EXPECT_STREQ("telephone-event", gcodec.plname);
456 // Test that we fail to set an unknown inbound codec.
457 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
458 EXPECT_TRUE(SetupEngine());
459 std::vector<cricket::AudioCodec> codecs;
460 codecs.push_back(kIsacCodec);
461 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
462 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
465 // Test that we fail if we have duplicate types in the inbound list.
466 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
467 EXPECT_TRUE(SetupEngine());
468 std::vector<cricket::AudioCodec> codecs;
469 codecs.push_back(kIsacCodec);
470 codecs.push_back(kCn16000Codec);
471 codecs[1].id = kIsacCodec.id;
472 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
475 // Test that we can decode OPUS without stereo parameters.
476 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
477 EXPECT_TRUE(SetupEngine());
478 EXPECT_TRUE(channel_->SetOptions(options_conference_));
479 std::vector<cricket::AudioCodec> codecs;
480 codecs.push_back(kIsacCodec);
481 codecs.push_back(kPcmuCodec);
482 codecs.push_back(kOpusCodec);
483 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
484 EXPECT_TRUE(channel_->AddRecvStream(
485 cricket::StreamParams::CreateLegacy(kSsrc1)));
486 int channel_num2 = voe_.GetLastChannel();
487 webrtc::CodecInst opus;
488 engine_.FindWebRtcCodec(kOpusCodec, &opus);
489 // Even without stereo parameters, recv codecs still specify channels = 2.
490 EXPECT_EQ(2, opus.channels);
491 EXPECT_EQ(111, opus.pltype);
492 EXPECT_STREQ("opus", opus.plname);
494 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
495 EXPECT_EQ(111, opus.pltype);
498 // Test that we can decode OPUS with stereo = 0.
499 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
500 EXPECT_TRUE(SetupEngine());
501 EXPECT_TRUE(channel_->SetOptions(options_conference_));
502 std::vector<cricket::AudioCodec> codecs;
503 codecs.push_back(kIsacCodec);
504 codecs.push_back(kPcmuCodec);
505 codecs.push_back(kOpusCodec);
506 codecs[2].params["stereo"] = "0";
507 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
508 EXPECT_TRUE(channel_->AddRecvStream(
509 cricket::StreamParams::CreateLegacy(kSsrc1)));
510 int channel_num2 = voe_.GetLastChannel();
511 webrtc::CodecInst opus;
512 engine_.FindWebRtcCodec(kOpusCodec, &opus);
513 // Even when stereo is off, recv codecs still specify channels = 2.
514 EXPECT_EQ(2, opus.channels);
515 EXPECT_EQ(111, opus.pltype);
516 EXPECT_STREQ("opus", opus.plname);
518 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
519 EXPECT_EQ(111, opus.pltype);
522 // Test that we can decode OPUS with stereo = 1.
523 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
524 EXPECT_TRUE(SetupEngine());
525 EXPECT_TRUE(channel_->SetOptions(options_conference_));
526 std::vector<cricket::AudioCodec> codecs;
527 codecs.push_back(kIsacCodec);
528 codecs.push_back(kPcmuCodec);
529 codecs.push_back(kOpusCodec);
530 codecs[2].params["stereo"] = "1";
531 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
532 EXPECT_TRUE(channel_->AddRecvStream(
533 cricket::StreamParams::CreateLegacy(kSsrc1)));
534 int channel_num2 = voe_.GetLastChannel();
535 webrtc::CodecInst opus;
536 engine_.FindWebRtcCodec(kOpusCodec, &opus);
537 EXPECT_EQ(2, opus.channels);
538 EXPECT_EQ(111, opus.pltype);
539 EXPECT_STREQ("opus", opus.plname);
541 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
542 EXPECT_EQ(111, opus.pltype);
545 // Test that changes to recv codecs are applied to all streams.
546 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
547 EXPECT_TRUE(SetupEngine());
548 EXPECT_TRUE(channel_->SetOptions(options_conference_));
549 std::vector<cricket::AudioCodec> codecs;
550 codecs.push_back(kIsacCodec);
551 codecs.push_back(kPcmuCodec);
552 codecs.push_back(kTelephoneEventCodec);
553 codecs[0].id = 106; // collide with existing telephone-event
555 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
556 EXPECT_TRUE(channel_->AddRecvStream(
557 cricket::StreamParams::CreateLegacy(kSsrc1)));
558 int channel_num2 = voe_.GetLastChannel();
559 webrtc::CodecInst gcodec;
560 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
561 gcodec.plfreq = 16000;
563 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
564 EXPECT_EQ(106, gcodec.pltype);
565 EXPECT_STREQ("ISAC", gcodec.plname);
566 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
568 gcodec.plfreq = 8000;
570 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
571 EXPECT_EQ(126, gcodec.pltype);
572 EXPECT_STREQ("telephone-event", gcodec.plname);
575 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
576 EXPECT_TRUE(SetupEngine());
577 EXPECT_TRUE(channel_->SetOptions(options_conference_));
578 std::vector<cricket::AudioCodec> codecs;
579 codecs.push_back(kIsacCodec);
580 codecs[0].id = 106; // collide with existing telephone-event
582 EXPECT_TRUE(channel_->AddRecvStream(
583 cricket::StreamParams::CreateLegacy(kSsrc1)));
584 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
586 int channel_num2 = voe_.GetLastChannel();
587 webrtc::CodecInst gcodec;
588 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
589 gcodec.plfreq = 16000;
591 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
592 EXPECT_EQ(106, gcodec.pltype);
593 EXPECT_STREQ("ISAC", gcodec.plname);
596 // Test that we can apply the same set of codecs again while playing.
597 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
598 EXPECT_TRUE(SetupEngine());
599 int channel_num = voe_.GetLastChannel();
600 std::vector<cricket::AudioCodec> codecs;
601 codecs.push_back(kIsacCodec);
602 codecs.push_back(kCn16000Codec);
603 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
604 EXPECT_TRUE(channel_->SetPlayout(true));
605 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607 // Changing the payload type of a codec should fail.
609 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
610 EXPECT_TRUE(voe_.GetPlayout(channel_num));
613 // Test that we can add a codec while playing.
614 TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
615 EXPECT_TRUE(SetupEngine());
616 int channel_num = voe_.GetLastChannel();
617 std::vector<cricket::AudioCodec> codecs;
618 codecs.push_back(kIsacCodec);
619 codecs.push_back(kCn16000Codec);
620 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
621 EXPECT_TRUE(channel_->SetPlayout(true));
623 codecs.push_back(kOpusCodec);
624 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
625 EXPECT_TRUE(voe_.GetPlayout(channel_num));
626 webrtc::CodecInst gcodec;
627 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
628 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
631 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
632 EXPECT_TRUE(SetupEngine());
633 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
635 // Test that when autobw is enabled, bitrate is kept as the default
636 // value. autobw is enabled for the following tests because the target
639 // ISAC, default bitrate == 32000.
640 TestSendBandwidth(kIsacCodec, 0, true, 32000);
642 // PCMU, default bitrate == 64000.
643 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
645 // CELT, default bitrate == 64000.
646 TestSendBandwidth(kCeltCodec, 0, true, 64000);
648 // opus, default bitrate == 64000.
649 TestSendBandwidth(kOpusCodec, -1, true, 64000);
652 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
653 EXPECT_TRUE(SetupEngine());
654 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
656 // Test that the bitrate of a multi-rate codec is always the maximum.
658 // ISAC, default bitrate == 32000.
659 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
660 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
662 // CELT, default bitrate == 64000.
663 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
664 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
666 // opus, default bitrate == 64000.
667 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
668 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
671 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
672 EXPECT_TRUE(SetupEngine());
673 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
675 // Test that we can only set a maximum bitrate for a fixed-rate codec
676 // if it's bigger than the fixed rate.
678 // PCMU, fixed bitrate == 64000.
679 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
680 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
681 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
682 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
683 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
684 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
685 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
688 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
689 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
690 channel_ = engine_.CreateChannel();
691 EXPECT_TRUE(channel_ != NULL);
692 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
694 int desired_bitrate = 128000;
695 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
697 EXPECT_TRUE(channel_->AddSendStream(
698 cricket::StreamParams::CreateLegacy(kSsrc1)));
700 int channel_num = voe_.GetLastChannel();
701 webrtc::CodecInst codec;
702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
703 EXPECT_EQ(desired_bitrate, codec.rate);
706 // Test that bitrate cannot be set for CBR codecs.
707 // Bitrate is ignored if it is higher than the fixed bitrate.
708 // Bitrate less then the fixed bitrate is an error.
709 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
710 EXPECT_TRUE(SetupEngine());
711 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
713 webrtc::CodecInst codec;
714 int channel_num = voe_.GetLastChannel();
715 std::vector<cricket::AudioCodec> codecs;
717 // PCMU, default bitrate == 64000.
718 codecs.push_back(kPcmuCodec);
719 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
720 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
721 EXPECT_EQ(64000, codec.rate);
722 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
723 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
724 EXPECT_EQ(64000, codec.rate);
725 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
726 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
727 EXPECT_EQ(64000, codec.rate);
730 // Test that we apply codecs properly.
731 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
732 EXPECT_TRUE(SetupEngine());
733 int channel_num = voe_.GetLastChannel();
734 std::vector<cricket::AudioCodec> codecs;
735 codecs.push_back(kIsacCodec);
736 codecs.push_back(kPcmuCodec);
737 codecs.push_back(kRedCodec);
739 codecs[0].bitrate = 48000;
740 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
741 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
742 webrtc::CodecInst gcodec;
743 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
744 EXPECT_EQ(96, gcodec.pltype);
745 EXPECT_EQ(48000, gcodec.rate);
746 EXPECT_STREQ("ISAC", gcodec.plname);
747 EXPECT_FALSE(voe_.GetVAD(channel_num));
748 EXPECT_FALSE(voe_.GetFEC(channel_num));
749 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
750 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
751 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
754 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
756 TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
757 EXPECT_TRUE(SetupEngine());
758 std::vector<cricket::AudioCodec> codecs;
759 codecs.push_back(kIsacCodec);
760 codecs.push_back(kPcmuCodec);
761 codecs.push_back(kRedCodec);
763 codecs[0].bitrate = 48000;
764 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
765 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
766 // Calling SetSendCodec again with same codec which is already set.
767 // In this case media channel shouldn't send codec to VoE.
768 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
769 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
772 // Test that if clockrate is not 48000 for opus, we fail.
773 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
774 EXPECT_TRUE(SetupEngine());
775 std::vector<cricket::AudioCodec> codecs;
776 codecs.push_back(kOpusCodec);
777 codecs[0].bitrate = 0;
778 codecs[0].clockrate = 50000;
779 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
782 // Test that if channels=0 for opus, we fail.
783 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
784 EXPECT_TRUE(SetupEngine());
785 std::vector<cricket::AudioCodec> codecs;
786 codecs.push_back(kOpusCodec);
787 codecs[0].bitrate = 0;
788 codecs[0].channels = 0;
789 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
792 // Test that if channels=0 for opus, we fail.
793 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
794 EXPECT_TRUE(SetupEngine());
795 std::vector<cricket::AudioCodec> codecs;
796 codecs.push_back(kOpusCodec);
797 codecs[0].bitrate = 0;
798 codecs[0].channels = 0;
799 codecs[0].params["stereo"] = "1";
800 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
803 // Test that if channel is 1 for opus and there's no stereo, we fail.
804 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
805 EXPECT_TRUE(SetupEngine());
806 std::vector<cricket::AudioCodec> codecs;
807 codecs.push_back(kOpusCodec);
808 codecs[0].bitrate = 0;
809 codecs[0].channels = 1;
810 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
813 // Test that if channel is 1 for opus and stereo=0, we fail.
814 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
815 EXPECT_TRUE(SetupEngine());
816 std::vector<cricket::AudioCodec> codecs;
817 codecs.push_back(kOpusCodec);
818 codecs[0].bitrate = 0;
819 codecs[0].channels = 1;
820 codecs[0].params["stereo"] = "0";
821 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
824 // Test that if channel is 1 for opus and stereo=1, we fail.
825 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
826 EXPECT_TRUE(SetupEngine());
827 std::vector<cricket::AudioCodec> codecs;
828 codecs.push_back(kOpusCodec);
829 codecs[0].bitrate = 0;
830 codecs[0].channels = 1;
831 codecs[0].params["stereo"] = "1";
832 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
835 // Test that with bitrate=0 and no stereo,
836 // channels and bitrate are 1 and 32000.
837 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
838 EXPECT_TRUE(SetupEngine());
839 int channel_num = voe_.GetLastChannel();
840 std::vector<cricket::AudioCodec> codecs;
841 codecs.push_back(kOpusCodec);
842 codecs[0].bitrate = 0;
843 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
844 webrtc::CodecInst gcodec;
845 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
846 EXPECT_STREQ("opus", gcodec.plname);
847 EXPECT_EQ(1, gcodec.channels);
848 EXPECT_EQ(32000, gcodec.rate);
851 // Test that with bitrate=0 and stereo=0,
852 // channels and bitrate are 1 and 32000.
853 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
854 EXPECT_TRUE(SetupEngine());
855 int channel_num = voe_.GetLastChannel();
856 std::vector<cricket::AudioCodec> codecs;
857 codecs.push_back(kOpusCodec);
858 codecs[0].bitrate = 0;
859 codecs[0].params["stereo"] = "0";
860 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
861 webrtc::CodecInst gcodec;
862 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
863 EXPECT_STREQ("opus", gcodec.plname);
864 EXPECT_EQ(1, gcodec.channels);
865 EXPECT_EQ(32000, gcodec.rate);
868 // Test that with bitrate=invalid and stereo=0,
869 // channels and bitrate are 1 and 32000.
870 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
871 EXPECT_TRUE(SetupEngine());
872 int channel_num = voe_.GetLastChannel();
873 std::vector<cricket::AudioCodec> codecs;
874 codecs.push_back(kOpusCodec);
875 codecs[0].params["stereo"] = "0";
876 webrtc::CodecInst gcodec;
878 // bitrate that's out of the range between 6000 and 510000 will be considered
879 // as invalid and ignored.
880 codecs[0].bitrate = 5999;
881 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
882 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
883 EXPECT_STREQ("opus", gcodec.plname);
884 EXPECT_EQ(1, gcodec.channels);
885 EXPECT_EQ(32000, gcodec.rate);
887 codecs[0].bitrate = 510001;
888 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
889 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
890 EXPECT_STREQ("opus", gcodec.plname);
891 EXPECT_EQ(1, gcodec.channels);
892 EXPECT_EQ(32000, gcodec.rate);
895 // Test that with bitrate=0 and stereo=1,
896 // channels and bitrate are 2 and 64000.
897 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
898 EXPECT_TRUE(SetupEngine());
899 int channel_num = voe_.GetLastChannel();
900 std::vector<cricket::AudioCodec> codecs;
901 codecs.push_back(kOpusCodec);
902 codecs[0].bitrate = 0;
903 codecs[0].params["stereo"] = "1";
904 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
905 webrtc::CodecInst gcodec;
906 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
907 EXPECT_STREQ("opus", gcodec.plname);
908 EXPECT_EQ(2, gcodec.channels);
909 EXPECT_EQ(64000, gcodec.rate);
912 // Test that with bitrate=invalid and stereo=1,
913 // channels and bitrate are 2 and 64000.
914 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
915 EXPECT_TRUE(SetupEngine());
916 int channel_num = voe_.GetLastChannel();
917 std::vector<cricket::AudioCodec> codecs;
918 codecs.push_back(kOpusCodec);
919 codecs[0].params["stereo"] = "1";
920 webrtc::CodecInst gcodec;
922 // bitrate that's out of the range between 6000 and 510000 will be considered
923 // as invalid and ignored.
924 codecs[0].bitrate = 5999;
925 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
926 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
927 EXPECT_STREQ("opus", gcodec.plname);
928 EXPECT_EQ(2, gcodec.channels);
929 EXPECT_EQ(64000, gcodec.rate);
931 codecs[0].bitrate = 510001;
932 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
933 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
934 EXPECT_STREQ("opus", gcodec.plname);
935 EXPECT_EQ(2, gcodec.channels);
936 EXPECT_EQ(64000, gcodec.rate);
939 // Test that with bitrate=N and stereo unset,
940 // channels and bitrate are 1 and N.
941 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
942 EXPECT_TRUE(SetupEngine());
943 int channel_num = voe_.GetLastChannel();
944 std::vector<cricket::AudioCodec> codecs;
945 codecs.push_back(kOpusCodec);
946 codecs[0].bitrate = 96000;
947 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
948 webrtc::CodecInst gcodec;
949 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
950 EXPECT_EQ(111, gcodec.pltype);
951 EXPECT_EQ(96000, gcodec.rate);
952 EXPECT_STREQ("opus", gcodec.plname);
953 EXPECT_EQ(1, gcodec.channels);
954 EXPECT_EQ(48000, gcodec.plfreq);
957 // Test that with bitrate=N and stereo=0,
958 // channels and bitrate are 1 and N.
959 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
960 EXPECT_TRUE(SetupEngine());
961 int channel_num = voe_.GetLastChannel();
962 std::vector<cricket::AudioCodec> codecs;
963 codecs.push_back(kOpusCodec);
964 codecs[0].bitrate = 30000;
965 codecs[0].params["stereo"] = "0";
966 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
967 webrtc::CodecInst gcodec;
968 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
969 EXPECT_EQ(1, gcodec.channels);
970 EXPECT_EQ(30000, gcodec.rate);
971 EXPECT_STREQ("opus", gcodec.plname);
974 // Test that with bitrate=N and without any parameters,
975 // channels and bitrate are 1 and N.
976 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
977 EXPECT_TRUE(SetupEngine());
978 int channel_num = voe_.GetLastChannel();
979 std::vector<cricket::AudioCodec> codecs;
980 codecs.push_back(kOpusCodec);
981 codecs[0].bitrate = 30000;
982 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
983 webrtc::CodecInst gcodec;
984 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
985 EXPECT_EQ(1, gcodec.channels);
986 EXPECT_EQ(30000, gcodec.rate);
987 EXPECT_STREQ("opus", gcodec.plname);
990 // Test that with bitrate=N and stereo=1,
991 // channels and bitrate are 2 and N.
992 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
993 EXPECT_TRUE(SetupEngine());
994 int channel_num = voe_.GetLastChannel();
995 std::vector<cricket::AudioCodec> codecs;
996 codecs.push_back(kOpusCodec);
997 codecs[0].bitrate = 30000;
998 codecs[0].params["stereo"] = "1";
999 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1000 webrtc::CodecInst gcodec;
1001 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1002 EXPECT_EQ(2, gcodec.channels);
1003 EXPECT_EQ(30000, gcodec.rate);
1004 EXPECT_STREQ("opus", gcodec.plname);
1007 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1008 // Also test that the "maxaveragebitrate" can't be set to values outside the
1009 // range of 6000 and 510000
1010 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1011 EXPECT_TRUE(SetupEngine());
1012 int channel_num = voe_.GetLastChannel();
1013 std::vector<cricket::AudioCodec> codecs;
1014 codecs.push_back(kOpusCodec);
1015 codecs[0].bitrate = 30000;
1016 webrtc::CodecInst gcodec;
1018 // Ignore if less than 6000.
1019 codecs[0].params["maxaveragebitrate"] = "5999";
1020 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1021 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1022 EXPECT_EQ(30000, gcodec.rate);
1024 // Ignore if larger than 510000.
1025 codecs[0].params["maxaveragebitrate"] = "510001";
1026 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1027 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1028 EXPECT_EQ(30000, gcodec.rate);
1030 codecs[0].params["maxaveragebitrate"] = "200000";
1031 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1032 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1033 EXPECT_EQ(200000, gcodec.rate);
1036 // Test that we can enable NACK with opus as caller.
1037 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1038 EXPECT_TRUE(SetupEngine());
1039 int channel_num = voe_.GetLastChannel();
1040 std::vector<cricket::AudioCodec> codecs;
1041 codecs.push_back(kOpusCodec);
1042 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1043 cricket::kParamValueEmpty));
1044 EXPECT_FALSE(voe_.GetNACK(channel_num));
1045 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1046 EXPECT_TRUE(voe_.GetNACK(channel_num));
1049 // Test that we can enable NACK with opus as callee.
1050 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1051 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1052 channel_ = engine_.CreateChannel();
1053 EXPECT_TRUE(channel_ != NULL);
1055 int channel_num = voe_.GetLastChannel();
1056 std::vector<cricket::AudioCodec> codecs;
1057 codecs.push_back(kOpusCodec);
1058 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1059 cricket::kParamValueEmpty));
1060 EXPECT_FALSE(voe_.GetNACK(channel_num));
1061 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1062 EXPECT_FALSE(voe_.GetNACK(channel_num));
1064 EXPECT_TRUE(channel_->AddSendStream(
1065 cricket::StreamParams::CreateLegacy(kSsrc1)));
1066 EXPECT_TRUE(voe_.GetNACK(channel_num));
1069 // Test that we can enable NACK on receive streams.
1070 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1071 EXPECT_TRUE(SetupEngine());
1072 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1073 int channel_num1 = voe_.GetLastChannel();
1074 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1075 int channel_num2 = voe_.GetLastChannel();
1076 std::vector<cricket::AudioCodec> codecs;
1077 codecs.push_back(kOpusCodec);
1078 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1079 cricket::kParamValueEmpty));
1080 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1081 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1082 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1083 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1084 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1087 // Test that we can disable NACK.
1088 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1089 EXPECT_TRUE(SetupEngine());
1090 int channel_num = voe_.GetLastChannel();
1091 std::vector<cricket::AudioCodec> codecs;
1092 codecs.push_back(kOpusCodec);
1093 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1094 cricket::kParamValueEmpty));
1095 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1096 EXPECT_TRUE(voe_.GetNACK(channel_num));
1099 codecs.push_back(kOpusCodec);
1100 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1101 EXPECT_FALSE(voe_.GetNACK(channel_num));
1104 // Test that we can disable NACK on receive streams.
1105 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1106 EXPECT_TRUE(SetupEngine());
1107 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1108 int channel_num1 = voe_.GetLastChannel();
1109 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1110 int channel_num2 = voe_.GetLastChannel();
1111 std::vector<cricket::AudioCodec> codecs;
1112 codecs.push_back(kOpusCodec);
1113 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1114 cricket::kParamValueEmpty));
1115 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1116 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1117 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1120 codecs.push_back(kOpusCodec);
1121 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1122 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1123 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1126 // Test that NACK is enabled on a new receive stream.
1127 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1128 EXPECT_TRUE(SetupEngine());
1129 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1130 int channel_num = voe_.GetLastChannel();
1131 std::vector<cricket::AudioCodec> codecs;
1132 codecs.push_back(kIsacCodec);
1133 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1134 cricket::kParamValueEmpty));
1135 codecs.push_back(kCn16000Codec);
1136 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1137 EXPECT_TRUE(voe_.GetNACK(channel_num));
1139 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1140 channel_num = voe_.GetLastChannel();
1141 EXPECT_TRUE(voe_.GetNACK(channel_num));
1142 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1143 channel_num = voe_.GetLastChannel();
1144 EXPECT_TRUE(voe_.GetNACK(channel_num));
1147 // Test that we can apply CELT with stereo mode but fail with mono mode.
1148 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1149 EXPECT_TRUE(SetupEngine());
1150 int channel_num = voe_.GetLastChannel();
1151 std::vector<cricket::AudioCodec> codecs;
1152 codecs.push_back(kCeltCodec);
1153 codecs.push_back(kIsacCodec);
1155 codecs[0].channels = 2;
1156 codecs[0].bitrate = 96000;
1157 codecs[1].bitrate = 64000;
1158 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1159 webrtc::CodecInst gcodec;
1160 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1161 EXPECT_EQ(96, gcodec.pltype);
1162 EXPECT_EQ(96000, gcodec.rate);
1163 EXPECT_EQ(2, gcodec.channels);
1164 EXPECT_STREQ("CELT", gcodec.plname);
1165 // Doesn't support mono, expect it to fall back to the next codec in the list.
1166 codecs[0].channels = 1;
1167 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1168 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1169 EXPECT_EQ(103, gcodec.pltype);
1170 EXPECT_EQ(1, gcodec.channels);
1171 EXPECT_EQ(64000, gcodec.rate);
1172 EXPECT_STREQ("ISAC", gcodec.plname);
1175 // Test that we can switch back and forth between CELT and ISAC with CN.
1176 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1177 EXPECT_TRUE(SetupEngine());
1178 int channel_num = voe_.GetLastChannel();
1179 std::vector<cricket::AudioCodec> celt_codecs;
1180 celt_codecs.push_back(kCeltCodec);
1181 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1182 webrtc::CodecInst gcodec;
1183 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1184 EXPECT_EQ(110, gcodec.pltype);
1185 EXPECT_STREQ("CELT", gcodec.plname);
1187 std::vector<cricket::AudioCodec> isac_codecs;
1188 isac_codecs.push_back(kIsacCodec);
1189 isac_codecs.push_back(kCn16000Codec);
1190 isac_codecs.push_back(kCeltCodec);
1191 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1192 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1193 EXPECT_EQ(103, gcodec.pltype);
1194 EXPECT_STREQ("ISAC", gcodec.plname);
1196 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1197 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1198 EXPECT_EQ(110, gcodec.pltype);
1199 EXPECT_STREQ("CELT", gcodec.plname);
1202 // Test that we handle various ways of specifying bitrate.
1203 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1204 EXPECT_TRUE(SetupEngine());
1205 int channel_num = voe_.GetLastChannel();
1206 std::vector<cricket::AudioCodec> codecs;
1207 codecs.push_back(kIsacCodec); // bitrate == 32000
1208 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1209 webrtc::CodecInst gcodec;
1210 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1211 EXPECT_EQ(103, gcodec.pltype);
1212 EXPECT_STREQ("ISAC", gcodec.plname);
1213 EXPECT_EQ(32000, gcodec.rate);
1215 codecs[0].bitrate = 0; // bitrate == default
1216 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1217 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1218 EXPECT_EQ(103, gcodec.pltype);
1219 EXPECT_STREQ("ISAC", gcodec.plname);
1220 EXPECT_EQ(-1, gcodec.rate);
1222 codecs[0].bitrate = 28000; // bitrate == 28000
1223 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1224 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1225 EXPECT_EQ(103, gcodec.pltype);
1226 EXPECT_STREQ("ISAC", gcodec.plname);
1227 EXPECT_EQ(28000, gcodec.rate);
1229 codecs[0] = kPcmuCodec; // bitrate == 64000
1230 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1231 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1232 EXPECT_EQ(0, gcodec.pltype);
1233 EXPECT_STREQ("PCMU", gcodec.plname);
1234 EXPECT_EQ(64000, gcodec.rate);
1236 codecs[0].bitrate = 0; // bitrate == default
1237 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1238 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1239 EXPECT_EQ(0, gcodec.pltype);
1240 EXPECT_STREQ("PCMU", gcodec.plname);
1241 EXPECT_EQ(64000, gcodec.rate);
1243 codecs[0] = kOpusCodec;
1244 codecs[0].bitrate = 0; // bitrate == default
1245 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1246 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1247 EXPECT_EQ(111, gcodec.pltype);
1248 EXPECT_STREQ("opus", gcodec.plname);
1249 EXPECT_EQ(32000, gcodec.rate);
1252 // Test that we fail if no codecs are specified.
1253 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1254 EXPECT_TRUE(SetupEngine());
1255 std::vector<cricket::AudioCodec> codecs;
1256 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1259 // Test that we can set send codecs even with telephone-event codec as the first
1261 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1262 EXPECT_TRUE(SetupEngine());
1263 int channel_num = voe_.GetLastChannel();
1264 std::vector<cricket::AudioCodec> codecs;
1265 codecs.push_back(kTelephoneEventCodec);
1266 codecs.push_back(kIsacCodec);
1267 codecs.push_back(kPcmuCodec);
1268 codecs[0].id = 98; // DTMF
1270 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1271 webrtc::CodecInst gcodec;
1272 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1273 EXPECT_EQ(96, gcodec.pltype);
1274 EXPECT_STREQ("ISAC", gcodec.plname);
1275 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1278 // Test that we can set send codecs even with CN codec as the first
1280 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1281 EXPECT_TRUE(SetupEngine());
1282 int channel_num = voe_.GetLastChannel();
1283 std::vector<cricket::AudioCodec> codecs;
1284 codecs.push_back(kCn16000Codec);
1285 codecs.push_back(kIsacCodec);
1286 codecs.push_back(kPcmuCodec);
1287 codecs[0].id = 98; // wideband CN
1289 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1290 webrtc::CodecInst gcodec;
1291 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1292 EXPECT_EQ(96, gcodec.pltype);
1293 EXPECT_STREQ("ISAC", gcodec.plname);
1294 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1297 // Test that we set VAD and DTMF types correctly as caller.
1298 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1299 EXPECT_TRUE(SetupEngine());
1300 int channel_num = voe_.GetLastChannel();
1301 std::vector<cricket::AudioCodec> codecs;
1302 codecs.push_back(kIsacCodec);
1303 codecs.push_back(kPcmuCodec);
1304 // TODO(juberti): cn 32000
1305 codecs.push_back(kCn16000Codec);
1306 codecs.push_back(kCn8000Codec);
1307 codecs.push_back(kTelephoneEventCodec);
1308 codecs.push_back(kRedCodec);
1310 codecs[2].id = 97; // wideband CN
1311 codecs[4].id = 98; // DTMF
1312 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1313 webrtc::CodecInst gcodec;
1314 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1315 EXPECT_EQ(96, gcodec.pltype);
1316 EXPECT_STREQ("ISAC", gcodec.plname);
1317 EXPECT_TRUE(voe_.GetVAD(channel_num));
1318 EXPECT_FALSE(voe_.GetFEC(channel_num));
1319 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1320 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1321 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1324 // Test that we set VAD and DTMF types correctly as callee.
1325 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1326 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1327 channel_ = engine_.CreateChannel();
1328 EXPECT_TRUE(channel_ != NULL);
1330 int channel_num = voe_.GetLastChannel();
1331 std::vector<cricket::AudioCodec> codecs;
1332 codecs.push_back(kIsacCodec);
1333 codecs.push_back(kPcmuCodec);
1334 // TODO(juberti): cn 32000
1335 codecs.push_back(kCn16000Codec);
1336 codecs.push_back(kCn8000Codec);
1337 codecs.push_back(kTelephoneEventCodec);
1338 codecs.push_back(kRedCodec);
1340 codecs[2].id = 97; // wideband CN
1341 codecs[4].id = 98; // DTMF
1342 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1343 EXPECT_TRUE(channel_->AddSendStream(
1344 cricket::StreamParams::CreateLegacy(kSsrc1)));
1346 webrtc::CodecInst gcodec;
1347 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1348 EXPECT_EQ(96, gcodec.pltype);
1349 EXPECT_STREQ("ISAC", gcodec.plname);
1350 EXPECT_TRUE(voe_.GetVAD(channel_num));
1351 EXPECT_FALSE(voe_.GetFEC(channel_num));
1352 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1353 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1354 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1357 // Test that we only apply VAD if we have a CN codec that matches the
1358 // send codec clockrate.
1359 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1360 EXPECT_TRUE(SetupEngine());
1361 int channel_num = voe_.GetLastChannel();
1362 std::vector<cricket::AudioCodec> codecs;
1363 // Set ISAC(16K) and CN(16K). VAD should be activated.
1364 codecs.push_back(kIsacCodec);
1365 codecs.push_back(kCn16000Codec);
1367 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1368 webrtc::CodecInst gcodec;
1369 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1370 EXPECT_STREQ("ISAC", gcodec.plname);
1371 EXPECT_TRUE(voe_.GetVAD(channel_num));
1372 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1373 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1374 codecs[0] = kPcmuCodec;
1375 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1376 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1377 EXPECT_STREQ("PCMU", gcodec.plname);
1378 EXPECT_FALSE(voe_.GetVAD(channel_num));
1379 // Set PCMU(8K) and CN(8K). VAD should be activated.
1380 codecs[1] = kCn8000Codec;
1381 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1382 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1383 EXPECT_STREQ("PCMU", gcodec.plname);
1384 EXPECT_TRUE(voe_.GetVAD(channel_num));
1385 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1386 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1387 codecs[0] = kIsacCodec;
1388 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1389 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1390 EXPECT_STREQ("ISAC", gcodec.plname);
1391 EXPECT_FALSE(voe_.GetVAD(channel_num));
1394 // Test that we perform case-insensitive matching of codec names.
1395 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1396 EXPECT_TRUE(SetupEngine());
1397 int channel_num = voe_.GetLastChannel();
1398 std::vector<cricket::AudioCodec> codecs;
1399 codecs.push_back(kIsacCodec);
1400 codecs.push_back(kPcmuCodec);
1401 codecs.push_back(kCn16000Codec);
1402 codecs.push_back(kCn8000Codec);
1403 codecs.push_back(kTelephoneEventCodec);
1404 codecs.push_back(kRedCodec);
1405 codecs[0].name = "iSaC";
1407 codecs[2].id = 97; // wideband CN
1408 codecs[4].id = 98; // DTMF
1409 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1410 webrtc::CodecInst gcodec;
1411 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1412 EXPECT_EQ(96, gcodec.pltype);
1413 EXPECT_STREQ("ISAC", gcodec.plname);
1414 EXPECT_TRUE(voe_.GetVAD(channel_num));
1415 EXPECT_FALSE(voe_.GetFEC(channel_num));
1416 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1417 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1418 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1421 // Test that we set up FEC correctly as caller.
1422 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1423 EXPECT_TRUE(SetupEngine());
1424 int channel_num = voe_.GetLastChannel();
1425 std::vector<cricket::AudioCodec> codecs;
1426 codecs.push_back(kRedCodec);
1427 codecs.push_back(kIsacCodec);
1428 codecs.push_back(kPcmuCodec);
1430 codecs[0].params[""] = "96/96";
1432 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1433 webrtc::CodecInst gcodec;
1434 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1435 EXPECT_EQ(96, gcodec.pltype);
1436 EXPECT_STREQ("ISAC", gcodec.plname);
1437 EXPECT_TRUE(voe_.GetFEC(channel_num));
1438 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1441 // Test that we set up FEC correctly as callee.
1442 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1443 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1444 channel_ = engine_.CreateChannel();
1445 EXPECT_TRUE(channel_ != NULL);
1447 int channel_num = voe_.GetLastChannel();
1448 std::vector<cricket::AudioCodec> codecs;
1449 codecs.push_back(kRedCodec);
1450 codecs.push_back(kIsacCodec);
1451 codecs.push_back(kPcmuCodec);
1453 codecs[0].params[""] = "96/96";
1455 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1456 EXPECT_TRUE(channel_->AddSendStream(
1457 cricket::StreamParams::CreateLegacy(kSsrc1)));
1458 webrtc::CodecInst gcodec;
1459 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1460 EXPECT_EQ(96, gcodec.pltype);
1461 EXPECT_STREQ("ISAC", gcodec.plname);
1462 EXPECT_TRUE(voe_.GetFEC(channel_num));
1463 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1466 // Test that we set up FEC correctly if params are omitted.
1467 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1468 EXPECT_TRUE(SetupEngine());
1469 int channel_num = voe_.GetLastChannel();
1470 std::vector<cricket::AudioCodec> codecs;
1471 codecs.push_back(kRedCodec);
1472 codecs.push_back(kIsacCodec);
1473 codecs.push_back(kPcmuCodec);
1476 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1477 webrtc::CodecInst gcodec;
1478 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1479 EXPECT_EQ(96, gcodec.pltype);
1480 EXPECT_STREQ("ISAC", gcodec.plname);
1481 EXPECT_TRUE(voe_.GetFEC(channel_num));
1482 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1485 // Test that we ignore RED if the parameters aren't named the way we expect.
1486 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1487 EXPECT_TRUE(SetupEngine());
1488 int channel_num = voe_.GetLastChannel();
1489 std::vector<cricket::AudioCodec> codecs;
1490 codecs.push_back(kRedCodec);
1491 codecs.push_back(kIsacCodec);
1492 codecs.push_back(kPcmuCodec);
1494 codecs[0].params["ABC"] = "96/96";
1496 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1497 webrtc::CodecInst gcodec;
1498 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499 EXPECT_EQ(96, gcodec.pltype);
1500 EXPECT_STREQ("ISAC", gcodec.plname);
1501 EXPECT_FALSE(voe_.GetFEC(channel_num));
1504 // Test that we ignore RED if it uses different primary/secondary encoding.
1505 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1506 EXPECT_TRUE(SetupEngine());
1507 int channel_num = voe_.GetLastChannel();
1508 std::vector<cricket::AudioCodec> codecs;
1509 codecs.push_back(kRedCodec);
1510 codecs.push_back(kIsacCodec);
1511 codecs.push_back(kPcmuCodec);
1513 codecs[0].params[""] = "96/0";
1515 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1516 webrtc::CodecInst gcodec;
1517 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1518 EXPECT_EQ(96, gcodec.pltype);
1519 EXPECT_STREQ("ISAC", gcodec.plname);
1520 EXPECT_FALSE(voe_.GetFEC(channel_num));
1523 // Test that we ignore RED if it uses more than 2 encodings.
1524 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1525 EXPECT_TRUE(SetupEngine());
1526 int channel_num = voe_.GetLastChannel();
1527 std::vector<cricket::AudioCodec> codecs;
1528 codecs.push_back(kRedCodec);
1529 codecs.push_back(kIsacCodec);
1530 codecs.push_back(kPcmuCodec);
1532 codecs[0].params[""] = "96/96/96";
1534 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1535 webrtc::CodecInst gcodec;
1536 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1537 EXPECT_EQ(96, gcodec.pltype);
1538 EXPECT_STREQ("ISAC", gcodec.plname);
1539 EXPECT_FALSE(voe_.GetFEC(channel_num));
1542 // Test that we ignore RED if it has bogus codec ids.
1543 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1544 EXPECT_TRUE(SetupEngine());
1545 int channel_num = voe_.GetLastChannel();
1546 std::vector<cricket::AudioCodec> codecs;
1547 codecs.push_back(kRedCodec);
1548 codecs.push_back(kIsacCodec);
1549 codecs.push_back(kPcmuCodec);
1551 codecs[0].params[""] = "ABC/ABC";
1553 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1554 webrtc::CodecInst gcodec;
1555 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1556 EXPECT_EQ(96, gcodec.pltype);
1557 EXPECT_STREQ("ISAC", gcodec.plname);
1558 EXPECT_FALSE(voe_.GetFEC(channel_num));
1561 // Test that we ignore RED if it refers to a codec that is not present.
1562 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1563 EXPECT_TRUE(SetupEngine());
1564 int channel_num = voe_.GetLastChannel();
1565 std::vector<cricket::AudioCodec> codecs;
1566 codecs.push_back(kRedCodec);
1567 codecs.push_back(kIsacCodec);
1568 codecs.push_back(kPcmuCodec);
1570 codecs[0].params[""] = "97/97";
1572 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1573 webrtc::CodecInst gcodec;
1574 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1575 EXPECT_EQ(96, gcodec.pltype);
1576 EXPECT_STREQ("ISAC", gcodec.plname);
1577 EXPECT_FALSE(voe_.GetFEC(channel_num));
1580 // Test support for audio level header extension.
1581 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1582 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1584 #ifdef USE_WEBRTC_DEV_BRANCH
1585 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1586 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1588 #endif // USE_WEBRTC_DEV_BRANCH
1590 // Test support for absolute send time header extension.
1591 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1592 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1594 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1595 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1598 // Test that we can create a channel and start sending/playing out on it.
1599 TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1600 EXPECT_TRUE(SetupEngine());
1601 int channel_num = voe_.GetLastChannel();
1602 std::vector<cricket::AudioCodec> codecs;
1603 codecs.push_back(kPcmuCodec);
1604 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1605 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1606 EXPECT_TRUE(voe_.GetSend(channel_num));
1607 EXPECT_TRUE(channel_->SetPlayout(true));
1608 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1609 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1610 EXPECT_FALSE(voe_.GetSend(channel_num));
1611 EXPECT_TRUE(channel_->SetPlayout(false));
1612 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1615 // Test that we can add and remove send streams.
1616 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1617 SetupForMultiSendStream();
1619 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1621 // Set the global state for sending.
1622 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1624 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1625 EXPECT_TRUE(channel_->AddSendStream(
1626 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1628 // Verify that we are in a sending state for all the created streams.
1629 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1630 EXPECT_TRUE(voe_.GetSend(channel_num));
1633 // Remove the first send channel, which is the default channel. It will only
1634 // recycle the default channel but not delete it.
1635 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1636 // Stream should already be Removed from the send stream list.
1637 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1638 // But the default still exists.
1639 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1641 // Delete the rest of send channel streams.
1642 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1643 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1644 // Stream should already be deleted.
1645 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1646 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1650 // Test SetSendCodecs correctly configure the codecs in all send streams.
1651 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1652 SetupForMultiSendStream();
1654 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1655 // Create send streams.
1656 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1657 EXPECT_TRUE(channel_->AddSendStream(
1658 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1661 std::vector<cricket::AudioCodec> codecs;
1662 // Set ISAC(16K) and CN(16K). VAD should be activated.
1663 codecs.push_back(kIsacCodec);
1664 codecs.push_back(kCn16000Codec);
1666 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1668 // Verify ISAC and VAD are corrected configured on all send channels.
1669 webrtc::CodecInst gcodec;
1670 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1671 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1672 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1673 EXPECT_STREQ("ISAC", gcodec.plname);
1674 EXPECT_TRUE(voe_.GetVAD(channel_num));
1675 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1678 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1679 codecs[0] = kPcmuCodec;
1680 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1681 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1682 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1683 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1684 EXPECT_STREQ("PCMU", gcodec.plname);
1685 EXPECT_FALSE(voe_.GetVAD(channel_num));
1689 // Test we can SetSend on all send streams correctly.
1690 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1691 SetupForMultiSendStream();
1693 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1694 // Create the send channels and they should be a SEND_NOTHING date.
1695 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1696 EXPECT_TRUE(channel_->AddSendStream(
1697 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1698 int channel_num = voe_.GetLastChannel();
1699 EXPECT_FALSE(voe_.GetSend(channel_num));
1702 // Set the global state for starting sending.
1703 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1704 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1705 // Verify that we are in a sending state for all the send streams.
1706 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1707 EXPECT_TRUE(voe_.GetSend(channel_num));
1710 // Set the global state for stopping sending.
1711 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1712 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1713 // Verify that we are in a stop state for all the send streams.
1714 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1715 EXPECT_FALSE(voe_.GetSend(channel_num));
1719 // Test we can set the correct statistics on all send streams.
1720 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1721 SetupForMultiSendStream();
1723 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1724 // Create send streams.
1725 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1726 EXPECT_TRUE(channel_->AddSendStream(
1727 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1730 // We need send codec to be set to get all stats.
1731 std::vector<cricket::AudioCodec> codecs;
1732 codecs.push_back(kPcmuCodec);
1733 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1735 cricket::VoiceMediaInfo info;
1736 EXPECT_EQ(true, channel_->GetStats(&info));
1737 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1739 // Verify the statistic information is correct.
1740 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1741 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
1742 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1743 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1744 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1745 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1746 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1747 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1748 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1749 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1752 EXPECT_EQ(1u, info.receivers.size());
1755 // Test that we can add and remove receive streams, and do proper send/playout.
1756 // We can receive on multiple streams while sending one stream.
1757 TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
1758 EXPECT_TRUE(SetupEngine());
1759 int channel_num1 = voe_.GetLastChannel();
1761 // Start playout on the default channel.
1762 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1763 EXPECT_TRUE(channel_->SetPlayout(true));
1764 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1766 // Adding another stream should disable playout on the default channel.
1767 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1768 int channel_num2 = voe_.GetLastChannel();
1769 std::vector<cricket::AudioCodec> codecs;
1770 codecs.push_back(kPcmuCodec);
1771 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1772 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1773 EXPECT_TRUE(voe_.GetSend(channel_num1));
1774 EXPECT_FALSE(voe_.GetSend(channel_num2));
1776 // Make sure only the new channel is played out.
1777 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1778 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1780 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1781 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1782 int channel_num3 = voe_.GetLastChannel();
1783 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1784 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1785 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1786 EXPECT_FALSE(voe_.GetSend(channel_num3));
1789 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1790 EXPECT_FALSE(voe_.GetSend(channel_num1));
1791 EXPECT_FALSE(voe_.GetSend(channel_num2));
1792 EXPECT_FALSE(voe_.GetSend(channel_num3));
1795 EXPECT_TRUE(channel_->SetPlayout(false));
1796 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1797 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1798 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1800 // Restart playout and make sure the default channel still is not played out.
1801 EXPECT_TRUE(channel_->SetPlayout(true));
1802 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1803 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1804 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1806 // Now remove the new streams and verify that the default channel is
1807 // played out again.
1808 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1809 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1811 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1814 // Test that we can set the devices to use.
1815 TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1816 EXPECT_TRUE(SetupEngine());
1817 int channel_num = voe_.GetLastChannel();
1818 std::vector<cricket::AudioCodec> codecs;
1819 codecs.push_back(kPcmuCodec);
1820 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1822 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1823 cricket::kFakeDefaultDeviceId);
1824 cricket::Device dev(cricket::kFakeDeviceName,
1825 cricket::kFakeDeviceId);
1827 // Test SetDevices() while not sending or playing.
1828 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1830 // Test SetDevices() while sending and playing.
1831 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1832 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1833 EXPECT_TRUE(channel_->SetPlayout(true));
1834 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1835 EXPECT_TRUE(voe_.GetSend(channel_num));
1836 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1838 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1840 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1841 EXPECT_TRUE(voe_.GetSend(channel_num));
1842 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1844 // Test that failure to open newly selected devices does not prevent opening
1846 voe_.set_fail_start_recording_microphone(true);
1847 voe_.set_playout_fail_channel(channel_num);
1848 voe_.set_send_fail_channel(channel_num);
1850 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1852 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1853 EXPECT_FALSE(voe_.GetSend(channel_num));
1854 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1856 voe_.set_fail_start_recording_microphone(false);
1857 voe_.set_playout_fail_channel(-1);
1858 voe_.set_send_fail_channel(-1);
1860 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1862 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1863 EXPECT_TRUE(voe_.GetSend(channel_num));
1864 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1867 // Test that we can set the devices to use even if we failed to
1868 // open the initial ones.
1869 TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1870 EXPECT_TRUE(SetupEngine());
1871 int channel_num = voe_.GetLastChannel();
1872 std::vector<cricket::AudioCodec> codecs;
1873 codecs.push_back(kPcmuCodec);
1874 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1876 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1877 cricket::kFakeDefaultDeviceId);
1878 cricket::Device dev(cricket::kFakeDeviceName,
1879 cricket::kFakeDeviceId);
1881 // Test that failure to open devices selected before starting
1882 // send/play does not prevent opening newly selected ones after that.
1883 voe_.set_fail_start_recording_microphone(true);
1884 voe_.set_playout_fail_channel(channel_num);
1885 voe_.set_send_fail_channel(channel_num);
1887 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1889 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1890 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1891 EXPECT_FALSE(channel_->SetPlayout(true));
1892 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1893 EXPECT_FALSE(voe_.GetSend(channel_num));
1894 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1896 voe_.set_fail_start_recording_microphone(false);
1897 voe_.set_playout_fail_channel(-1);
1898 voe_.set_send_fail_channel(-1);
1900 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1902 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1903 EXPECT_TRUE(voe_.GetSend(channel_num));
1904 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1907 // Test that we can create a channel configured for multi-point conferences,
1908 // and start sending/playing out on it.
1909 TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
1910 EXPECT_TRUE(SetupEngine());
1911 int channel_num = voe_.GetLastChannel();
1912 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1913 std::vector<cricket::AudioCodec> codecs;
1914 codecs.push_back(kPcmuCodec);
1915 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1916 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1917 EXPECT_TRUE(voe_.GetSend(channel_num));
1920 // Test that we can create a channel configured for Codian bridges,
1921 // and start sending/playing out on it.
1922 TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
1923 EXPECT_TRUE(SetupEngine());
1924 int channel_num = voe_.GetLastChannel();
1925 webrtc::AgcConfig agc_config;
1926 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1927 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1928 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
1929 std::vector<cricket::AudioCodec> codecs;
1930 codecs.push_back(kPcmuCodec);
1931 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1932 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1933 EXPECT_TRUE(voe_.GetSend(channel_num));
1934 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1935 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
1936 EXPECT_TRUE(channel_->SetPlayout(true));
1937 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1938 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1939 EXPECT_FALSE(voe_.GetSend(channel_num));
1940 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1941 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
1942 EXPECT_TRUE(channel_->SetPlayout(false));
1943 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1946 TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
1947 EXPECT_TRUE(SetupEngine());
1948 webrtc::AgcConfig agc_config;
1949 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1950 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1952 cricket::AudioOptions options;
1953 options.tx_agc_target_dbov.Set(3);
1954 options.tx_agc_digital_compression_gain.Set(9);
1955 options.tx_agc_limiter.Set(true);
1956 options.auto_gain_control.Set(true);
1957 EXPECT_TRUE(engine_.SetOptions(options));
1959 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1960 EXPECT_EQ(3, agc_config.targetLeveldBOv);
1961 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
1962 EXPECT_TRUE(agc_config.limiterEnable);
1964 // Check interaction with adjust_agc_delta. Both should be respected, for
1965 // backwards compatibility.
1966 options.adjust_agc_delta.Set(-10);
1967 EXPECT_TRUE(engine_.SetOptions(options));
1969 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1970 EXPECT_EQ(13, agc_config.targetLeveldBOv);
1973 TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
1974 EXPECT_TRUE(SetupEngine());
1975 int channel_num = voe_.GetLastChannel();
1976 cricket::AudioOptions options;
1977 options.rx_agc_target_dbov.Set(6);
1978 options.rx_agc_digital_compression_gain.Set(0);
1979 options.rx_agc_limiter.Set(true);
1980 options.rx_auto_gain_control.Set(true);
1981 EXPECT_TRUE(channel_->SetOptions(options));
1983 webrtc::AgcConfig agc_config;
1984 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
1985 channel_num, agc_config));
1986 EXPECT_EQ(6, agc_config.targetLeveldBOv);
1987 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
1988 EXPECT_TRUE(agc_config.limiterEnable);
1991 TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
1992 EXPECT_TRUE(SetupEngine());
1993 cricket::AudioOptions options;
1994 options.recording_sample_rate.Set(48000u);
1995 options.playout_sample_rate.Set(44100u);
1996 EXPECT_TRUE(engine_.SetOptions(options));
1998 unsigned int recording_sample_rate, playout_sample_rate;
1999 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2000 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2001 EXPECT_EQ(48000u, recording_sample_rate);
2002 EXPECT_EQ(44100u, playout_sample_rate);
2005 TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2006 EXPECT_TRUE(SetupEngine());
2007 engine_.SetLogging(talk_base::LS_INFO, "");
2010 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2012 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2014 webrtc::kTraceError | webrtc::kTraceCritical,
2015 static_cast<int>(trace_wrapper_->filter_));
2016 // Now set it explicitly
2017 std::string filter =
2018 "tracefilter " + talk_base::ToString(webrtc::kTraceDefault);
2019 engine_.SetLogging(talk_base::LS_VERBOSE, filter.c_str());
2020 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2021 trace_wrapper_->filter_);
2024 // Test that we can set the outgoing SSRC properly.
2025 // SSRC is set in SetupEngine by calling AddSendStream.
2026 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2027 EXPECT_TRUE(SetupEngine());
2028 int channel_num = voe_.GetLastChannel();
2029 unsigned int send_ssrc;
2030 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2031 EXPECT_NE(0U, send_ssrc);
2032 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2033 EXPECT_EQ(kSsrc1, send_ssrc);
2036 TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2037 // Setup. We need send codec to be set to get all stats.
2038 EXPECT_TRUE(SetupEngine());
2039 std::vector<cricket::AudioCodec> codecs;
2040 codecs.push_back(kPcmuCodec);
2041 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2043 cricket::VoiceMediaInfo info;
2044 EXPECT_EQ(true, channel_->GetStats(&info));
2045 EXPECT_EQ(1u, info.senders.size());
2046 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
2047 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2048 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2049 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2050 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2051 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2052 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2053 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2054 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2055 // TODO(sriniv): Add testing for more fields. These are not populated
2056 // in FakeWebrtcVoiceEngine yet.
2057 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2058 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2059 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2060 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2061 // EXPECT_EQ(cricket::kIntStatValue,
2062 // info.senders[0].echo_return_loss_enhancement);
2064 EXPECT_EQ(1u, info.receivers.size());
2065 // TODO(sriniv): Add testing for receiver fields.
2068 // Test that we can set the outgoing SSRC properly with multiple streams.
2069 // SSRC is set in SetupEngine by calling AddSendStream.
2070 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2071 EXPECT_TRUE(SetupEngine());
2072 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2073 int channel_num1 = voe_.GetLastChannel();
2074 unsigned int send_ssrc;
2075 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2076 EXPECT_EQ(kSsrc1, send_ssrc);
2078 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2079 int channel_num2 = voe_.GetLastChannel();
2080 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2081 EXPECT_EQ(kSsrc1, send_ssrc);
2084 // Test that the local SSRC is the same on sending and receiving channels if the
2085 // receive channel is created before the send channel.
2086 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2087 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2088 channel_ = engine_.CreateChannel();
2089 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2091 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2092 int receive_channel_num = voe_.GetLastChannel();
2093 EXPECT_TRUE(channel_->AddSendStream(
2094 cricket::StreamParams::CreateLegacy(1234)));
2095 int send_channel_num = voe_.GetLastChannel();
2097 unsigned int ssrc = 0;
2098 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2099 EXPECT_EQ(1234U, ssrc);
2101 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2102 EXPECT_EQ(1234U, ssrc);
2105 // Test that we can properly receive packets.
2106 TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2107 EXPECT_TRUE(SetupEngine());
2108 int channel_num = voe_.GetLastChannel();
2109 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2110 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2111 sizeof(kPcmuFrame)));
2114 // Test that we can properly receive packets on multiple streams.
2115 TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2116 EXPECT_TRUE(SetupEngine());
2117 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2118 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2119 int channel_num1 = voe_.GetLastChannel();
2120 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2121 int channel_num2 = voe_.GetLastChannel();
2122 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2123 int channel_num3 = voe_.GetLastChannel();
2124 // Create packets with the right SSRCs.
2125 char packets[4][sizeof(kPcmuFrame)];
2126 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2127 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2128 talk_base::SetBE32(packets[i] + 8, static_cast<uint32>(i));
2130 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2131 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2132 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2133 DeliverPacket(packets[0], sizeof(packets[0]));
2134 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2135 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2136 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2137 DeliverPacket(packets[1], sizeof(packets[1]));
2138 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2139 sizeof(packets[1])));
2140 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2141 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2142 DeliverPacket(packets[2], sizeof(packets[2]));
2143 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2144 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2145 sizeof(packets[2])));
2146 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2147 DeliverPacket(packets[3], sizeof(packets[3]));
2148 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2149 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2150 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2151 sizeof(packets[3])));
2152 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2153 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2154 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2157 // Test that we properly handle failures to add a stream.
2158 TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2159 EXPECT_TRUE(SetupEngine());
2160 voe_.set_fail_create_channel(true);
2161 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2162 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2164 // In 1:1 call, we should not try to create a new channel.
2165 cricket::AudioOptions options_no_conference_;
2166 options_no_conference_.conference_mode.Set(false);
2167 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2168 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2171 // Test that AddRecvStream doesn't create new channel for 1:1 call.
2172 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2173 EXPECT_TRUE(SetupEngine());
2174 int channel_num = voe_.GetLastChannel();
2175 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2176 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2179 // Test that after adding a recv stream, we do not decode more codecs than
2180 // those previously passed into SetRecvCodecs.
2181 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2182 EXPECT_TRUE(SetupEngine());
2183 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2184 std::vector<cricket::AudioCodec> codecs;
2185 codecs.push_back(kIsacCodec);
2186 codecs.push_back(kPcmuCodec);
2187 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2188 EXPECT_TRUE(channel_->AddRecvStream(
2189 cricket::StreamParams::CreateLegacy(kSsrc1)));
2190 int channel_num2 = voe_.GetLastChannel();
2191 webrtc::CodecInst gcodec;
2192 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2193 gcodec.plfreq = 32000;
2194 gcodec.channels = 2;
2195 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2198 // Test that we properly clean up any streams that were added, even if
2199 // not explicitly removed.
2200 TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2201 EXPECT_TRUE(SetupEngine());
2202 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2203 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2204 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2205 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2208 EXPECT_EQ(0, voe_.GetNumChannels());
2211 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2212 EXPECT_TRUE(SetupEngine());
2213 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2216 TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2217 EXPECT_TRUE(SetupEngine());
2218 // Stream 1 reuses default channel.
2219 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2220 // Manually delete default channel to simulate a failure.
2221 int default_channel = voe_.GetLastChannel();
2222 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2223 // Add recv stream 2 should fail because default channel is gone.
2224 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2225 int new_channel = voe_.GetLastChannel();
2226 EXPECT_NE(default_channel, new_channel);
2227 // The last created channel should have already been deleted.
2228 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2231 // Test the InsertDtmf on default send stream as caller.
2232 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2233 TestInsertDtmf(0, true);
2236 // Test the InsertDtmf on default send stream as callee
2237 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2238 TestInsertDtmf(0, false);
2241 // Test the InsertDtmf on specified send stream as caller.
2242 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2243 TestInsertDtmf(kSsrc1, true);
2246 // Test the InsertDtmf on specified send stream as callee.
2247 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2248 TestInsertDtmf(kSsrc1, false);
2251 // Test that we can play a ringback tone properly in a single-stream call.
2252 TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2253 EXPECT_TRUE(SetupEngine());
2254 int channel_num = voe_.GetLastChannel();
2255 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2256 // Check we fail if no ringback tone specified.
2257 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2258 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2259 // Check we can set and play a ringback tone.
2260 EXPECT_TRUE(channel_->SetRingbackTone(
2261 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2262 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2263 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2264 // Check we can stop the tone manually.
2265 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2266 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2267 // Check we stop the tone if a packet arrives.
2268 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2269 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2270 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2271 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2274 // Test that we can play a ringback tone properly in a multi-stream call.
2275 TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2276 EXPECT_TRUE(SetupEngine());
2277 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2278 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2279 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2280 int channel_num = voe_.GetLastChannel();
2281 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2282 // Check we fail if no ringback tone specified.
2283 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2284 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2285 // Check we can set and play a ringback tone on the correct ssrc.
2286 EXPECT_TRUE(channel_->SetRingbackTone(
2287 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2288 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2289 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2290 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2291 // Check we can stop the tone manually.
2292 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2293 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2294 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2295 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2296 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2297 // Send a packet with SSRC 1; the tone should not stop.
2298 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2299 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2300 // Send a packet with SSRC 2; the tone should stop.
2301 char packet[sizeof(kPcmuFrame)];
2302 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2303 talk_base::SetBE32(packet + 8, 2);
2304 DeliverPacket(packet, sizeof(packet));
2305 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2308 // Tests creating soundclips, and make sure they come from the right engine.
2309 TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2310 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2311 EXPECT_FALSE(voe_sc_.IsInited());
2312 soundclip_ = engine_.CreateSoundclip();
2313 EXPECT_TRUE(voe_sc_.IsInited());
2314 ASSERT_TRUE(soundclip_ != NULL);
2315 EXPECT_EQ(0, voe_.GetNumChannels());
2316 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2317 int channel_num = voe_sc_.GetLastChannel();
2318 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2321 EXPECT_EQ(0, voe_sc_.GetNumChannels());
2322 // Make sure the soundclip engine is uninitialized on shutdown, now that
2323 // we've initialized it by creating a soundclip.
2324 engine_.Terminate();
2325 EXPECT_FALSE(voe_sc_.IsInited());
2328 // Tests playing out a fake sound.
2329 TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2330 static const char kZeroes[16000] = {};
2331 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2332 soundclip_ = engine_.CreateSoundclip();
2333 ASSERT_TRUE(soundclip_ != NULL);
2334 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2337 TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2338 talk_base::scoped_ptr<ChannelErrorListener> listener;
2339 cricket::WebRtcVoiceMediaChannel* media_channel;
2340 unsigned int ssrc = 0;
2342 EXPECT_TRUE(SetupEngine());
2343 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2344 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2346 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2347 listener.reset(new ChannelErrorListener(channel_));
2349 // Test on WebRtc VoE channel.
2350 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2351 VE_SATURATION_WARNING);
2352 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2354 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2355 EXPECT_EQ(ssrc, listener->ssrc());
2358 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2359 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2361 EXPECT_EQ(0U, listener->ssrc());
2363 // Add another stream and test on that.
2365 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2368 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2369 VE_SATURATION_WARNING);
2370 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2372 EXPECT_EQ(ssrc, listener->ssrc());
2374 // Testing a non-existing channel.
2376 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2377 VE_SATURATION_WARNING);
2378 EXPECT_EQ(0, listener->error());
2381 TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2382 EXPECT_TRUE(SetupEngine());
2383 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2384 std::vector<cricket::AudioCodec> codecs;
2385 codecs.push_back(kPcmuCodec);
2386 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2387 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2388 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2389 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2390 EXPECT_TRUE(channel_->SetPlayout(true));
2391 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2392 EXPECT_TRUE(channel_->SetPlayout(false));
2393 EXPECT_FALSE(channel_->SetPlayout(true));
2396 // Test that the Registering/Unregistering with the
2397 // webrtcvoiceengine works as expected
2398 TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2399 EXPECT_TRUE(SetupEngine());
2400 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2401 EXPECT_TRUE(channel_->AddRecvStream(
2402 cricket::StreamParams::CreateLegacy(kSsrc2)));
2403 cricket::FakeMediaProcessor vp_1;
2404 cricket::FakeMediaProcessor vp_2;
2406 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2407 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2408 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2409 voe_.TriggerProcessPacket(cricket::MPD_RX);
2410 voe_.TriggerProcessPacket(cricket::MPD_TX);
2412 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2413 EXPECT_EQ(1, vp_1.voice_frame_count());
2414 EXPECT_EQ(1, vp_2.voice_frame_count());
2416 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2419 voe_.TriggerProcessPacket(cricket::MPD_RX);
2420 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2421 EXPECT_EQ(1, vp_2.voice_frame_count());
2422 EXPECT_EQ(2, vp_1.voice_frame_count());
2424 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2427 voe_.TriggerProcessPacket(cricket::MPD_RX);
2428 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2429 EXPECT_EQ(2, vp_1.voice_frame_count());
2431 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2432 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2433 voe_.TriggerProcessPacket(cricket::MPD_RX);
2434 voe_.TriggerProcessPacket(cricket::MPD_TX);
2435 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2436 EXPECT_EQ(3, vp_1.voice_frame_count());
2438 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2440 cricket::MPD_RX_AND_TX));
2441 voe_.TriggerProcessPacket(cricket::MPD_TX);
2442 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2443 EXPECT_EQ(3, vp_1.voice_frame_count());
2444 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2445 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2446 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2448 // Test that we can register a processor on the receive channel on SSRC 0.
2449 // This tests the 1:1 case when the receive SSRC is unknown.
2450 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2451 voe_.TriggerProcessPacket(cricket::MPD_RX);
2452 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2453 EXPECT_EQ(4, vp_1.voice_frame_count());
2454 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2458 // The following tests test that FindChannelNumFromSsrc is doing
2460 // pick an invalid ssrc and make sure we can't register
2461 EXPECT_FALSE(engine_.RegisterProcessor(99,
2464 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2465 EXPECT_TRUE(engine_.RegisterProcessor(1,
2468 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2471 EXPECT_FALSE(engine_.RegisterProcessor(1,
2474 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2477 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2478 EXPECT_TRUE(SetupEngine());
2481 webrtc::EcModes ec_mode;
2482 bool ec_metrics_enabled;
2483 webrtc::AecmModes aecm_mode;
2486 webrtc::AgcModes agc_mode;
2487 webrtc::AgcConfig agc_config;
2489 webrtc::NsModes ns_mode;
2490 bool highpass_filter_enabled;
2491 bool stereo_swapping_enabled;
2492 bool typing_detection_enabled;
2493 voe_.GetEcStatus(ec_enabled, ec_mode);
2494 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2495 voe_.GetAecmMode(aecm_mode, cng_enabled);
2496 voe_.GetAgcStatus(agc_enabled, agc_mode);
2497 voe_.GetAgcConfig(agc_config);
2498 voe_.GetNsStatus(ns_enabled, ns_mode);
2499 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2500 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2501 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2502 EXPECT_TRUE(ec_enabled);
2503 EXPECT_TRUE(ec_metrics_enabled);
2504 EXPECT_FALSE(cng_enabled);
2505 EXPECT_TRUE(agc_enabled);
2506 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2507 EXPECT_TRUE(ns_enabled);
2508 EXPECT_TRUE(highpass_filter_enabled);
2509 EXPECT_FALSE(stereo_swapping_enabled);
2510 EXPECT_TRUE(typing_detection_enabled);
2511 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2512 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2514 // Nothing set, so all ignored.
2515 cricket::AudioOptions options;
2516 ASSERT_TRUE(engine_.SetOptions(options));
2517 voe_.GetEcStatus(ec_enabled, ec_mode);
2518 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2519 voe_.GetAecmMode(aecm_mode, cng_enabled);
2520 voe_.GetAgcStatus(agc_enabled, agc_mode);
2521 voe_.GetAgcConfig(agc_config);
2522 voe_.GetNsStatus(ns_enabled, ns_mode);
2523 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2524 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2525 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2526 EXPECT_TRUE(ec_enabled);
2527 EXPECT_TRUE(ec_metrics_enabled);
2528 EXPECT_FALSE(cng_enabled);
2529 EXPECT_TRUE(agc_enabled);
2530 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2531 EXPECT_TRUE(ns_enabled);
2532 EXPECT_TRUE(highpass_filter_enabled);
2533 EXPECT_FALSE(stereo_swapping_enabled);
2534 EXPECT_TRUE(typing_detection_enabled);
2535 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2536 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2538 // Turn echo cancellation off
2539 options.echo_cancellation.Set(false);
2540 ASSERT_TRUE(engine_.SetOptions(options));
2541 voe_.GetEcStatus(ec_enabled, ec_mode);
2542 EXPECT_FALSE(ec_enabled);
2544 // Turn echo cancellation back on, with settings, and make sure
2545 // nothing else changed.
2546 options.echo_cancellation.Set(true);
2547 ASSERT_TRUE(engine_.SetOptions(options));
2548 voe_.GetEcStatus(ec_enabled, ec_mode);
2549 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2550 voe_.GetAecmMode(aecm_mode, cng_enabled);
2551 voe_.GetAgcStatus(agc_enabled, agc_mode);
2552 voe_.GetAgcConfig(agc_config);
2553 voe_.GetNsStatus(ns_enabled, ns_mode);
2554 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2555 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2556 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2557 EXPECT_TRUE(ec_enabled);
2558 EXPECT_TRUE(ec_metrics_enabled);
2559 EXPECT_TRUE(agc_enabled);
2560 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2561 EXPECT_TRUE(ns_enabled);
2562 EXPECT_TRUE(highpass_filter_enabled);
2563 EXPECT_FALSE(stereo_swapping_enabled);
2564 EXPECT_TRUE(typing_detection_enabled);
2565 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2566 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2569 options.auto_gain_control.Set(false);
2570 ASSERT_TRUE(engine_.SetOptions(options));
2571 voe_.GetAgcStatus(agc_enabled, agc_mode);
2572 EXPECT_FALSE(agc_enabled);
2575 options.auto_gain_control.Set(true);
2576 options.adjust_agc_delta.Clear();
2577 ASSERT_TRUE(engine_.SetOptions(options));
2578 voe_.GetAgcStatus(agc_enabled, agc_mode);
2579 EXPECT_TRUE(agc_enabled);
2580 voe_.GetAgcConfig(agc_config);
2581 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2583 // Turn off other options (and stereo swapping on).
2584 options.noise_suppression.Set(false);
2585 options.highpass_filter.Set(false);
2586 options.typing_detection.Set(false);
2587 options.stereo_swapping.Set(true);
2588 ASSERT_TRUE(engine_.SetOptions(options));
2589 voe_.GetNsStatus(ns_enabled, ns_mode);
2590 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2591 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2592 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2593 EXPECT_FALSE(ns_enabled);
2594 EXPECT_FALSE(highpass_filter_enabled);
2595 EXPECT_FALSE(typing_detection_enabled);
2596 EXPECT_TRUE(stereo_swapping_enabled);
2598 // Turn on "conference mode" to ensure it has no impact.
2599 options.conference_mode.Set(true);
2600 ASSERT_TRUE(engine_.SetOptions(options));
2601 voe_.GetEcStatus(ec_enabled, ec_mode);
2602 voe_.GetNsStatus(ns_enabled, ns_mode);
2603 EXPECT_TRUE(ec_enabled);
2604 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2605 EXPECT_FALSE(ns_enabled);
2606 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2609 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2610 EXPECT_TRUE(SetupEngine());
2613 webrtc::EcModes ec_mode;
2614 bool ec_metrics_enabled;
2616 webrtc::AgcModes agc_mode;
2618 webrtc::NsModes ns_mode;
2619 bool highpass_filter_enabled;
2620 bool stereo_swapping_enabled;
2621 bool typing_detection_enabled;
2623 voe_.GetEcStatus(ec_enabled, ec_mode);
2624 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2625 voe_.GetAgcStatus(agc_enabled, agc_mode);
2626 voe_.GetNsStatus(ns_enabled, ns_mode);
2627 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2628 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2629 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2630 EXPECT_TRUE(ec_enabled);
2631 EXPECT_TRUE(agc_enabled);
2632 EXPECT_TRUE(ns_enabled);
2633 EXPECT_TRUE(highpass_filter_enabled);
2634 EXPECT_TRUE(typing_detection_enabled);
2635 EXPECT_FALSE(stereo_swapping_enabled);
2638 TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2639 webrtc::AgcConfig set_config = {0};
2640 set_config.targetLeveldBOv = 3;
2641 set_config.digitalCompressionGaindB = 9;
2642 set_config.limiterEnable = true;
2643 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2644 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2646 webrtc::AgcConfig config = {0};
2647 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2648 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2649 EXPECT_EQ(set_config.digitalCompressionGaindB,
2650 config.digitalCompressionGaindB);
2651 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2654 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2655 EXPECT_TRUE(SetupEngine());
2656 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2657 engine_.CreateChannel());
2658 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2659 engine_.CreateChannel());
2661 // Have to add a stream to make SetSend work.
2662 cricket::StreamParams stream1;
2663 stream1.ssrcs.push_back(1);
2664 channel1->AddSendStream(stream1);
2665 cricket::StreamParams stream2;
2666 stream2.ssrcs.push_back(2);
2667 channel2->AddSendStream(stream2);
2669 // AEC and AGC and NS
2670 cricket::AudioOptions options_all;
2671 options_all.echo_cancellation.Set(true);
2672 options_all.auto_gain_control.Set(true);
2673 options_all.noise_suppression.Set(true);
2675 ASSERT_TRUE(channel1->SetOptions(options_all));
2676 cricket::AudioOptions expected_options = options_all;
2677 cricket::AudioOptions actual_options;
2678 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2679 EXPECT_EQ(expected_options, actual_options);
2680 ASSERT_TRUE(channel2->SetOptions(options_all));
2681 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2682 EXPECT_EQ(expected_options, actual_options);
2685 cricket::AudioOptions options_no_ns;
2686 options_no_ns.noise_suppression.Set(false);
2687 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2689 expected_options.echo_cancellation.Set(true);
2690 expected_options.auto_gain_control.Set(true);
2691 expected_options.noise_suppression.Set(false);
2692 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2693 EXPECT_EQ(expected_options, actual_options);
2696 cricket::AudioOptions options_no_agc;
2697 options_no_agc.auto_gain_control.Set(false);
2698 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2700 expected_options.echo_cancellation.Set(true);
2701 expected_options.auto_gain_control.Set(false);
2702 expected_options.noise_suppression.Set(true);
2703 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2704 EXPECT_EQ(expected_options, actual_options);
2706 ASSERT_TRUE(engine_.SetOptions(options_all));
2708 webrtc::EcModes ec_mode;
2710 webrtc::AgcModes agc_mode;
2712 webrtc::NsModes ns_mode;
2713 voe_.GetEcStatus(ec_enabled, ec_mode);
2714 voe_.GetAgcStatus(agc_enabled, agc_mode);
2715 voe_.GetNsStatus(ns_enabled, ns_mode);
2716 EXPECT_TRUE(ec_enabled);
2717 EXPECT_TRUE(agc_enabled);
2718 EXPECT_TRUE(ns_enabled);
2720 channel1->SetSend(cricket::SEND_MICROPHONE);
2721 voe_.GetEcStatus(ec_enabled, ec_mode);
2722 voe_.GetAgcStatus(agc_enabled, agc_mode);
2723 voe_.GetNsStatus(ns_enabled, ns_mode);
2724 EXPECT_TRUE(ec_enabled);
2725 EXPECT_TRUE(agc_enabled);
2726 EXPECT_FALSE(ns_enabled);
2728 channel1->SetSend(cricket::SEND_NOTHING);
2729 voe_.GetEcStatus(ec_enabled, ec_mode);
2730 voe_.GetAgcStatus(agc_enabled, agc_mode);
2731 voe_.GetNsStatus(ns_enabled, ns_mode);
2732 EXPECT_TRUE(ec_enabled);
2733 EXPECT_TRUE(agc_enabled);
2734 EXPECT_TRUE(ns_enabled);
2736 channel2->SetSend(cricket::SEND_MICROPHONE);
2737 voe_.GetEcStatus(ec_enabled, ec_mode);
2738 voe_.GetAgcStatus(agc_enabled, agc_mode);
2739 voe_.GetNsStatus(ns_enabled, ns_mode);
2740 EXPECT_TRUE(ec_enabled);
2741 EXPECT_FALSE(agc_enabled);
2742 EXPECT_TRUE(ns_enabled);
2744 channel2->SetSend(cricket::SEND_NOTHING);
2745 voe_.GetEcStatus(ec_enabled, ec_mode);
2746 voe_.GetAgcStatus(agc_enabled, agc_mode);
2747 voe_.GetNsStatus(ns_enabled, ns_mode);
2748 EXPECT_TRUE(ec_enabled);
2749 EXPECT_TRUE(agc_enabled);
2750 EXPECT_TRUE(ns_enabled);
2752 // Make sure settings take effect while we are sending.
2753 ASSERT_TRUE(engine_.SetOptions(options_all));
2754 cricket::AudioOptions options_no_agc_nor_ns;
2755 options_no_agc_nor_ns.auto_gain_control.Set(false);
2756 options_no_agc_nor_ns.noise_suppression.Set(false);
2757 channel2->SetSend(cricket::SEND_MICROPHONE);
2758 channel2->SetOptions(options_no_agc_nor_ns);
2760 expected_options.echo_cancellation.Set(true);
2761 expected_options.auto_gain_control.Set(false);
2762 expected_options.noise_suppression.Set(false);
2763 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2764 EXPECT_EQ(expected_options, actual_options);
2765 voe_.GetEcStatus(ec_enabled, ec_mode);
2766 voe_.GetAgcStatus(agc_enabled, agc_mode);
2767 voe_.GetNsStatus(ns_enabled, ns_mode);
2768 EXPECT_TRUE(ec_enabled);
2769 EXPECT_FALSE(agc_enabled);
2770 EXPECT_FALSE(ns_enabled);
2773 // This test verifies DSCP settings are properly applied on voice media channel.
2774 TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2775 EXPECT_TRUE(SetupEngine());
2776 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel(
2777 engine_.CreateChannel());
2778 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2779 new cricket::FakeNetworkInterface);
2780 channel->SetInterface(network_interface.get());
2781 cricket::AudioOptions options;
2782 options.dscp.Set(true);
2783 EXPECT_TRUE(channel->SetOptions(options));
2784 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
2785 // Verify previous value is not modified if dscp option is not set.
2786 cricket::AudioOptions options1;
2787 EXPECT_TRUE(channel->SetOptions(options1));
2788 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
2789 options.dscp.Set(false);
2790 EXPECT_TRUE(channel->SetOptions(options));
2791 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp());
2794 TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2795 cricket::WebRtcVoiceEngine engine;
2796 cricket::AudioOptions options = engine.GetOptions();
2797 // The default options should have at least a few things set. We purposefully
2798 // don't check the option values here, though.
2799 EXPECT_TRUE(options.echo_cancellation.IsSet());
2800 EXPECT_TRUE(options.auto_gain_control.IsSet());
2801 EXPECT_TRUE(options.noise_suppression.IsSet());
2804 // Test that GetReceiveChannelNum returns the default channel for the first
2805 // recv stream in 1-1 calls.
2806 TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2807 EXPECT_TRUE(SetupEngine());
2808 cricket::WebRtcVoiceMediaChannel* media_channel =
2809 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2810 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2811 EXPECT_EQ(media_channel->voe_channel(),
2812 media_channel->GetReceiveChannelNum(0));
2813 cricket::StreamParams stream;
2814 stream.ssrcs.push_back(kSsrc2);
2815 EXPECT_TRUE(channel_->AddRecvStream(stream));
2816 EXPECT_EQ(media_channel->voe_channel(),
2817 media_channel->GetReceiveChannelNum(kSsrc2));
2820 // Test that GetReceiveChannelNum doesn't return the default channel for the
2821 // first recv stream in conference calls.
2822 TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2823 EXPECT_TRUE(SetupEngine());
2824 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2825 cricket::StreamParams stream;
2826 stream.ssrcs.push_back(kSsrc2);
2827 EXPECT_TRUE(channel_->AddRecvStream(stream));
2828 cricket::WebRtcVoiceMediaChannel* media_channel =
2829 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2830 EXPECT_LT(media_channel->voe_channel(),
2831 media_channel->GetReceiveChannelNum(kSsrc2));
2834 TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2835 EXPECT_TRUE(SetupEngine());
2837 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2838 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2839 EXPECT_DOUBLE_EQ(1, left);
2840 EXPECT_DOUBLE_EQ(2, right);
2842 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2843 cricket::StreamParams stream;
2844 stream.ssrcs.push_back(kSsrc2);
2845 EXPECT_TRUE(channel_->AddRecvStream(stream));
2847 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2848 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2849 EXPECT_DOUBLE_EQ(2, left);
2850 EXPECT_DOUBLE_EQ(1, right);
2853 // Tests for the actual WebRtc VoE library.
2855 // Tests that the library initializes and shuts down properly.
2856 TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2857 cricket::WebRtcVoiceEngine engine;
2858 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2859 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2860 EXPECT_TRUE(channel != NULL);
2864 // Reinit to catch regression where VoiceEngineObserver reference is lost
2865 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2869 // Tests that the logging from the library is cleartext.
2870 TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2871 cricket::WebRtcVoiceEngine engine;
2872 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2873 new talk_base::MemoryStream);
2875 bool cleartext = true;
2876 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2877 engine.SetLogging(talk_base::LS_VERBOSE, "");
2878 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2879 EXPECT_TRUE(stream->GetSize(&size));
2880 EXPECT_GT(size, 0U);
2882 talk_base::LogMessage::RemoveLogToStream(stream.get());
2883 const char* buf = stream->GetBuffer();
2884 for (size_t i = 0; i < size && cleartext; ++i) {
2885 int ch = static_cast<int>(buf[i]);
2886 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
2888 cleartext = (isprint(ch) || isspace(ch));
2890 EXPECT_TRUE(cleartext);
2893 // Tests we do not see any references to a monitor thread being spun up
2894 // when initiating the engine.
2895 TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
2896 cricket::WebRtcVoiceEngine engine;
2897 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2898 new talk_base::MemoryStream);
2899 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2900 engine.SetLogging(talk_base::LS_VERBOSE, "");
2901 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2903 talk_base::LogMessage::RemoveLogToStream(stream.get());
2906 EXPECT_TRUE(stream->GetSize(&size));
2907 EXPECT_GT(size, 0U);
2908 const std::string logs(stream->GetBuffer(), size);
2909 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
2912 // Tests that the library is configured with the codecs we want.
2913 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
2914 cricket::WebRtcVoiceEngine engine;
2915 // Check codecs by name.
2916 EXPECT_TRUE(engine.FindCodec(
2917 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
2918 EXPECT_TRUE(engine.FindCodec(
2919 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
2920 EXPECT_TRUE(engine.FindCodec(
2921 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
2922 // Check that name matching is case-insensitive.
2923 EXPECT_TRUE(engine.FindCodec(
2924 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
2925 EXPECT_TRUE(engine.FindCodec(
2926 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
2927 EXPECT_TRUE(engine.FindCodec(
2928 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
2929 EXPECT_TRUE(engine.FindCodec(
2930 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
2931 EXPECT_TRUE(engine.FindCodec(
2932 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
2933 EXPECT_TRUE(engine.FindCodec(
2934 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
2935 EXPECT_TRUE(engine.FindCodec(
2936 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
2937 EXPECT_TRUE(engine.FindCodec(
2938 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
2939 EXPECT_TRUE(engine.FindCodec(
2940 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
2941 EXPECT_TRUE(engine.FindCodec(
2942 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
2943 // Check codecs with an id by id.
2944 EXPECT_TRUE(engine.FindCodec(
2945 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
2946 EXPECT_TRUE(engine.FindCodec(
2947 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
2948 EXPECT_TRUE(engine.FindCodec(
2949 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
2950 EXPECT_TRUE(engine.FindCodec(
2951 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
2952 // Check sample/bitrate matching.
2953 EXPECT_TRUE(engine.FindCodec(
2954 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
2955 // Check that bad codecs fail.
2956 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
2957 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
2958 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
2959 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
2960 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
2961 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
2962 for (std::vector<cricket::AudioCodec>::const_iterator it =
2963 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
2964 if (it->name == "CN" && it->clockrate == 16000) {
2965 EXPECT_EQ(105, it->id);
2966 } else if (it->name == "CN" && it->clockrate == 32000) {
2967 EXPECT_EQ(106, it->id);
2968 } else if (it->name == "ISAC" && it->clockrate == 16000) {
2969 EXPECT_EQ(103, it->id);
2970 } else if (it->name == "ISAC" && it->clockrate == 32000) {
2971 EXPECT_EQ(104, it->id);
2972 } else if (it->name == "G722" && it->clockrate == 16000) {
2973 EXPECT_EQ(9, it->id);
2974 } else if (it->name == "telephone-event") {
2975 EXPECT_EQ(126, it->id);
2976 } else if (it->name == "red") {
2977 EXPECT_EQ(127, it->id);
2978 } else if (it->name == "opus") {
2979 EXPECT_EQ(111, it->id);
2980 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
2981 EXPECT_EQ("10", it->params.find("minptime")->second);
2982 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
2983 EXPECT_EQ("60", it->params.find("maxptime")->second);
2990 // Tests that VoE supports at least 32 channels
2991 TEST(WebRtcVoiceEngineTest, Has32Channels) {
2992 cricket::WebRtcVoiceEngine engine;
2993 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2995 cricket::VoiceMediaChannel* channels[32];
2996 int num_channels = 0;
2998 while (num_channels < ARRAY_SIZE(channels)) {
2999 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3003 channels[num_channels++] = channel;
3006 int expected = ARRAY_SIZE(channels);
3007 EXPECT_EQ(expected, num_channels);
3009 while (num_channels > 0) {
3010 delete channels[--num_channels];
3016 // Test that we set our preferred codecs properly.
3017 TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3018 cricket::WebRtcVoiceEngine engine;
3019 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3020 cricket::WebRtcVoiceMediaChannel channel(&engine);
3021 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3025 // Test our workarounds to WebRtc VoE' munging of the coinit count
3026 TEST(WebRtcVoiceEngineTest, CoInitialize) {
3027 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3029 // Initial refcount should be 0.
3030 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3032 // Engine should start even with COM already inited.
3033 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3034 engine->Terminate();
3035 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3036 engine->Terminate();
3038 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3039 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3040 // Decrement refcount to (hopefully) 0.
3045 // Ensure refcount is 0.
3046 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));