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 "webrtc/base/win32.h"
33 #include "webrtc/base/byteorder.h"
34 #include "webrtc/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/webrtcvie.h"
42 #include "talk/media/webrtc/webrtcvoiceengine.h"
43 #include "talk/p2p/base/fakesession.h"
44 #include "talk/session/media/channel.h"
46 // Tests for the WebRtcVoiceEngine/VoiceChannel code.
48 using cricket::kRtpAudioLevelHeaderExtension;
49 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
51 static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
52 static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
53 static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
54 static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
55 static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
56 static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
57 static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
58 static const cricket::AudioCodec
59 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
60 static const cricket::AudioCodec* const kAudioCodecs[] = {
61 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
62 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
64 const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
65 static uint32 kSsrc1 = 0x99;
66 static uint32 kSsrc2 = 0x98;
68 class FakeVoEWrapper : public cricket::VoEWrapper {
70 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
71 : cricket::VoEWrapper(engine, // processing
86 class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
88 virtual int SetTraceFilter(const unsigned int filter) {
92 virtual int SetTraceFile(const char* fileNameUTF8) {
95 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
101 class WebRtcVoiceEngineTestFake : public testing::Test {
103 class ChannelErrorListener : public sigslot::has_slots<> {
105 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
106 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
107 ASSERT(channel != NULL);
108 channel->SignalMediaError.connect(
109 this, &ChannelErrorListener::OnVoiceChannelError);
111 void OnVoiceChannelError(uint32 ssrc,
112 cricket::VoiceMediaChannel::Error error) {
118 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
120 uint32 ssrc() const {
123 cricket::VoiceMediaChannel::Error error() const {
129 cricket::VoiceMediaChannel::Error error_;
132 WebRtcVoiceEngineTestFake()
133 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
134 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
135 trace_wrapper_(new FakeVoETraceWrapper()),
136 engine_(new FakeVoEWrapper(&voe_),
137 new FakeVoEWrapper(&voe_sc_),
139 channel_(NULL), soundclip_(NULL) {
140 options_conference_.conference_mode.Set(true);
141 options_adjust_agc_.adjust_agc_delta.Set(-10);
143 bool SetupEngineWithoutStream() {
144 if (!engine_.Init(rtc::Thread::Current())) {
147 channel_ = engine_.CreateChannel();
148 return (channel_ != NULL);
151 if (!SetupEngineWithoutStream()) {
154 return channel_->AddSendStream(
155 cricket::StreamParams::CreateLegacy(kSsrc1));
157 void SetupForMultiSendStream() {
158 EXPECT_TRUE(SetupEngine());
159 // Remove stream added in Setup, which is corresponding to default channel.
160 int default_channel_num = voe_.GetLastChannel();
161 uint32 default_send_ssrc = 0u;
162 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
163 EXPECT_EQ(kSsrc1, default_send_ssrc);
164 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
166 // Verify the default channel still exists.
167 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
169 void DeliverPacket(const void* data, int len) {
170 rtc::Buffer packet(data, len);
171 channel_->OnPacketReceived(&packet, rtc::PacketTime());
173 virtual void TearDown() {
179 void TestInsertDtmf(uint32 ssrc, bool caller) {
180 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
181 channel_ = engine_.CreateChannel();
182 EXPECT_TRUE(channel_ != NULL);
184 // if this is a caller, local description will be applied and add the
186 EXPECT_TRUE(channel_->AddSendStream(
187 cricket::StreamParams::CreateLegacy(kSsrc1)));
189 int channel_id = voe_.GetLastChannel();
191 // Test we can only InsertDtmf when the other side supports telephone-event.
192 std::vector<cricket::AudioCodec> codecs;
193 codecs.push_back(kPcmuCodec);
194 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
195 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
196 EXPECT_FALSE(channel_->CanInsertDtmf());
197 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
198 codecs.push_back(kTelephoneEventCodec);
199 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
200 EXPECT_TRUE(channel_->CanInsertDtmf());
203 // There's no active send channel yet.
204 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
205 EXPECT_TRUE(channel_->AddSendStream(
206 cricket::StreamParams::CreateLegacy(kSsrc1)));
209 // Check we fail if the ssrc is invalid.
210 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
213 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
214 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
215 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
218 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
219 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
220 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
222 // Test send and play
223 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
224 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
225 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
226 cricket::DF_PLAY | cricket::DF_SEND));
227 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
228 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
231 // Test that send bandwidth is set correctly.
232 // |codec| is the codec under test.
233 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
234 // |expected_result| is the expected result from SetMaxSendBandwidth().
235 // |expected_bitrate| is the expected audio bitrate afterward.
236 void TestSendBandwidth(const cricket::AudioCodec& codec,
238 bool expected_result,
239 int expected_bitrate) {
240 int channel_num = voe_.GetLastChannel();
241 std::vector<cricket::AudioCodec> codecs;
243 codecs.push_back(codec);
244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
246 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
247 EXPECT_EQ(expected_result, result);
249 webrtc::CodecInst temp_codec;
250 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
252 EXPECT_EQ(expected_bitrate, temp_codec.rate);
255 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
256 EXPECT_TRUE(SetupEngineWithoutStream());
257 int channel_num = voe_.GetLastChannel();
259 // Ensure extensions are off by default.
260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
262 std::vector<cricket::RtpHeaderExtension> extensions;
263 // Ensure unknown extensions won't cause an error.
264 extensions.push_back(cricket::RtpHeaderExtension(
265 "urn:ietf:params:unknownextention", 1));
266 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
267 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
269 // Ensure extensions stay off with an empty list of headers.
271 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
272 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
274 // Ensure extension is set properly.
276 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
277 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
278 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
280 // Ensure extension is set properly on new channel.
281 // The first stream to occupy the default channel.
282 EXPECT_TRUE(channel_->AddSendStream(
283 cricket::StreamParams::CreateLegacy(123)));
284 EXPECT_TRUE(channel_->AddSendStream(
285 cricket::StreamParams::CreateLegacy(234)));
286 int new_channel_num = voe_.GetLastChannel();
287 EXPECT_NE(channel_num, new_channel_num);
288 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
290 // Ensure all extensions go back off with an empty list.
292 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
293 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
294 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
297 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
298 EXPECT_TRUE(SetupEngineWithoutStream());
299 int channel_num = voe_.GetLastChannel();
301 // Ensure extensions are off by default.
302 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
304 std::vector<cricket::RtpHeaderExtension> extensions;
305 // Ensure unknown extensions won't cause an error.
306 extensions.push_back(cricket::RtpHeaderExtension(
307 "urn:ietf:params:unknownextention", 1));
308 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
309 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
311 // Ensure extensions stay off with an empty list of headers.
313 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
314 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
316 // Ensure extension is set properly.
318 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
319 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
320 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
322 // Ensure extension is set properly on new channel.
323 // The first stream to occupy the default channel.
324 EXPECT_TRUE(channel_->AddRecvStream(
325 cricket::StreamParams::CreateLegacy(345)));
326 EXPECT_TRUE(channel_->AddRecvStream(
327 cricket::StreamParams::CreateLegacy(456)));
328 int new_channel_num = voe_.GetLastChannel();
329 EXPECT_NE(channel_num, new_channel_num);
330 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
332 // Ensure all extensions go back off with an empty list.
334 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
335 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
336 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
340 cricket::FakeWebRtcVoiceEngine voe_;
341 cricket::FakeWebRtcVoiceEngine voe_sc_;
342 FakeVoETraceWrapper* trace_wrapper_;
343 cricket::WebRtcVoiceEngine engine_;
344 cricket::VoiceMediaChannel* channel_;
345 cricket::SoundclipMedia* soundclip_;
347 cricket::AudioOptions options_conference_;
348 cricket::AudioOptions options_adjust_agc_;
351 // Tests that our stub library "works".
352 TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
353 EXPECT_FALSE(voe_.IsInited());
354 EXPECT_FALSE(voe_sc_.IsInited());
355 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
356 EXPECT_TRUE(voe_.IsInited());
357 // The soundclip engine is lazily initialized.
358 EXPECT_FALSE(voe_sc_.IsInited());
360 EXPECT_FALSE(voe_.IsInited());
361 EXPECT_FALSE(voe_sc_.IsInited());
364 // Tests that we can create and destroy a channel.
365 TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
366 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
367 channel_ = engine_.CreateChannel();
368 EXPECT_TRUE(channel_ != NULL);
371 // Tests that we properly handle failures in CreateChannel.
372 TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
373 voe_.set_fail_create_channel(true);
374 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
375 channel_ = engine_.CreateChannel();
376 EXPECT_TRUE(channel_ == NULL);
379 // Tests that the list of supported codecs is created properly and ordered
381 TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
382 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
383 ASSERT_FALSE(codecs.empty());
384 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
385 EXPECT_EQ(48000, codecs[0].clockrate);
386 EXPECT_EQ(2, codecs[0].channels);
387 EXPECT_EQ(64000, codecs[0].bitrate);
388 int pref = codecs[0].preference;
389 for (size_t i = 1; i < codecs.size(); ++i) {
390 EXPECT_GT(pref, codecs[i].preference);
391 pref = codecs[i].preference;
395 // Tests that we can find codecs by name or id, and that we interpret the
396 // clockrate and bitrate fields properly.
397 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
398 cricket::AudioCodec codec;
399 webrtc::CodecInst codec_inst;
400 // Find PCMU with explicit clockrate and bitrate.
401 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
402 // Find ISAC with explicit clockrate and 0 bitrate.
403 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
404 // Find telephone-event with explicit clockrate and 0 bitrate.
405 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
406 // Find ISAC with a different payload id.
409 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
410 EXPECT_EQ(codec.id, codec_inst.pltype);
411 // Find PCMU with a 0 clockrate.
414 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
415 EXPECT_EQ(codec.id, codec_inst.pltype);
416 EXPECT_EQ(8000, codec_inst.plfreq);
417 // Find PCMU with a 0 bitrate.
420 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
421 EXPECT_EQ(codec.id, codec_inst.pltype);
422 EXPECT_EQ(64000, codec_inst.rate);
423 // Find ISAC with an explicit bitrate.
425 codec.bitrate = 32000;
426 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
427 EXPECT_EQ(codec.id, codec_inst.pltype);
428 EXPECT_EQ(32000, codec_inst.rate);
431 // Test that we set our inbound codecs properly, including changing PT.
432 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
433 EXPECT_TRUE(SetupEngine());
434 int channel_num = voe_.GetLastChannel();
435 std::vector<cricket::AudioCodec> codecs;
436 codecs.push_back(kIsacCodec);
437 codecs.push_back(kPcmuCodec);
438 codecs.push_back(kTelephoneEventCodec);
439 codecs[0].id = 106; // collide with existing telephone-event
441 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
442 webrtc::CodecInst gcodec;
443 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
444 gcodec.plfreq = 16000;
446 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
447 EXPECT_EQ(106, gcodec.pltype);
448 EXPECT_STREQ("ISAC", gcodec.plname);
449 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
451 gcodec.plfreq = 8000;
452 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
453 EXPECT_EQ(126, gcodec.pltype);
454 EXPECT_STREQ("telephone-event", gcodec.plname);
457 // Test that we fail to set an unknown inbound codec.
458 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
459 EXPECT_TRUE(SetupEngine());
460 std::vector<cricket::AudioCodec> codecs;
461 codecs.push_back(kIsacCodec);
462 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
463 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
466 // Test that we fail if we have duplicate types in the inbound list.
467 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
468 EXPECT_TRUE(SetupEngine());
469 std::vector<cricket::AudioCodec> codecs;
470 codecs.push_back(kIsacCodec);
471 codecs.push_back(kCn16000Codec);
472 codecs[1].id = kIsacCodec.id;
473 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
476 // Test that we can decode OPUS without stereo parameters.
477 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
478 EXPECT_TRUE(SetupEngine());
479 EXPECT_TRUE(channel_->SetOptions(options_conference_));
480 std::vector<cricket::AudioCodec> codecs;
481 codecs.push_back(kIsacCodec);
482 codecs.push_back(kPcmuCodec);
483 codecs.push_back(kOpusCodec);
484 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
485 EXPECT_TRUE(channel_->AddRecvStream(
486 cricket::StreamParams::CreateLegacy(kSsrc1)));
487 int channel_num2 = voe_.GetLastChannel();
488 webrtc::CodecInst opus;
489 engine_.FindWebRtcCodec(kOpusCodec, &opus);
490 // Even without stereo parameters, recv codecs still specify channels = 2.
491 EXPECT_EQ(2, opus.channels);
492 EXPECT_EQ(111, opus.pltype);
493 EXPECT_STREQ("opus", opus.plname);
495 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
496 EXPECT_EQ(111, opus.pltype);
499 // Test that we can decode OPUS with stereo = 0.
500 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
501 EXPECT_TRUE(SetupEngine());
502 EXPECT_TRUE(channel_->SetOptions(options_conference_));
503 std::vector<cricket::AudioCodec> codecs;
504 codecs.push_back(kIsacCodec);
505 codecs.push_back(kPcmuCodec);
506 codecs.push_back(kOpusCodec);
507 codecs[2].params["stereo"] = "0";
508 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
509 EXPECT_TRUE(channel_->AddRecvStream(
510 cricket::StreamParams::CreateLegacy(kSsrc1)));
511 int channel_num2 = voe_.GetLastChannel();
512 webrtc::CodecInst opus;
513 engine_.FindWebRtcCodec(kOpusCodec, &opus);
514 // Even when stereo is off, recv codecs still specify channels = 2.
515 EXPECT_EQ(2, opus.channels);
516 EXPECT_EQ(111, opus.pltype);
517 EXPECT_STREQ("opus", opus.plname);
519 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
520 EXPECT_EQ(111, opus.pltype);
523 // Test that we can decode OPUS with stereo = 1.
524 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
525 EXPECT_TRUE(SetupEngine());
526 EXPECT_TRUE(channel_->SetOptions(options_conference_));
527 std::vector<cricket::AudioCodec> codecs;
528 codecs.push_back(kIsacCodec);
529 codecs.push_back(kPcmuCodec);
530 codecs.push_back(kOpusCodec);
531 codecs[2].params["stereo"] = "1";
532 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
533 EXPECT_TRUE(channel_->AddRecvStream(
534 cricket::StreamParams::CreateLegacy(kSsrc1)));
535 int channel_num2 = voe_.GetLastChannel();
536 webrtc::CodecInst opus;
537 engine_.FindWebRtcCodec(kOpusCodec, &opus);
538 EXPECT_EQ(2, opus.channels);
539 EXPECT_EQ(111, opus.pltype);
540 EXPECT_STREQ("opus", opus.plname);
542 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
543 EXPECT_EQ(111, opus.pltype);
546 // Test that changes to recv codecs are applied to all streams.
547 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
548 EXPECT_TRUE(SetupEngine());
549 EXPECT_TRUE(channel_->SetOptions(options_conference_));
550 std::vector<cricket::AudioCodec> codecs;
551 codecs.push_back(kIsacCodec);
552 codecs.push_back(kPcmuCodec);
553 codecs.push_back(kTelephoneEventCodec);
554 codecs[0].id = 106; // collide with existing telephone-event
556 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
557 EXPECT_TRUE(channel_->AddRecvStream(
558 cricket::StreamParams::CreateLegacy(kSsrc1)));
559 int channel_num2 = voe_.GetLastChannel();
560 webrtc::CodecInst gcodec;
561 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
562 gcodec.plfreq = 16000;
564 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
565 EXPECT_EQ(106, gcodec.pltype);
566 EXPECT_STREQ("ISAC", gcodec.plname);
567 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
569 gcodec.plfreq = 8000;
571 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
572 EXPECT_EQ(126, gcodec.pltype);
573 EXPECT_STREQ("telephone-event", gcodec.plname);
576 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
577 EXPECT_TRUE(SetupEngine());
578 EXPECT_TRUE(channel_->SetOptions(options_conference_));
579 std::vector<cricket::AudioCodec> codecs;
580 codecs.push_back(kIsacCodec);
581 codecs[0].id = 106; // collide with existing telephone-event
583 EXPECT_TRUE(channel_->AddRecvStream(
584 cricket::StreamParams::CreateLegacy(kSsrc1)));
585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
587 int channel_num2 = voe_.GetLastChannel();
588 webrtc::CodecInst gcodec;
589 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
590 gcodec.plfreq = 16000;
592 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
593 EXPECT_EQ(106, gcodec.pltype);
594 EXPECT_STREQ("ISAC", gcodec.plname);
597 // Test that we can apply the same set of codecs again while playing.
598 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
599 EXPECT_TRUE(SetupEngine());
600 int channel_num = voe_.GetLastChannel();
601 std::vector<cricket::AudioCodec> codecs;
602 codecs.push_back(kIsacCodec);
603 codecs.push_back(kCn16000Codec);
604 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
605 EXPECT_TRUE(channel_->SetPlayout(true));
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
608 // Changing the payload type of a codec should fail.
610 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
611 EXPECT_TRUE(voe_.GetPlayout(channel_num));
614 // Test that we can add a codec while playing.
615 TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
616 EXPECT_TRUE(SetupEngine());
617 int channel_num = voe_.GetLastChannel();
618 std::vector<cricket::AudioCodec> codecs;
619 codecs.push_back(kIsacCodec);
620 codecs.push_back(kCn16000Codec);
621 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
622 EXPECT_TRUE(channel_->SetPlayout(true));
624 codecs.push_back(kOpusCodec);
625 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
626 EXPECT_TRUE(voe_.GetPlayout(channel_num));
627 webrtc::CodecInst gcodec;
628 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
629 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
632 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
633 EXPECT_TRUE(SetupEngine());
634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
636 // Test that when autobw is enabled, bitrate is kept as the default
637 // value. autobw is enabled for the following tests because the target
640 // ISAC, default bitrate == 32000.
641 TestSendBandwidth(kIsacCodec, 0, true, 32000);
643 // PCMU, default bitrate == 64000.
644 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
646 // CELT, default bitrate == 64000.
647 TestSendBandwidth(kCeltCodec, 0, true, 64000);
649 // opus, default bitrate == 64000.
650 TestSendBandwidth(kOpusCodec, -1, true, 64000);
653 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
654 EXPECT_TRUE(SetupEngine());
655 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
657 // Test that the bitrate of a multi-rate codec is always the maximum.
659 // ISAC, default bitrate == 32000.
660 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
661 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
663 // CELT, default bitrate == 64000.
664 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
665 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
667 // opus, default bitrate == 64000.
668 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
669 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
672 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
673 EXPECT_TRUE(SetupEngine());
674 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
676 // Test that we can only set a maximum bitrate for a fixed-rate codec
677 // if it's bigger than the fixed rate.
679 // PCMU, fixed bitrate == 64000.
680 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
681 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
682 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
683 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
684 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
685 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
686 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
689 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
690 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
691 channel_ = engine_.CreateChannel();
692 EXPECT_TRUE(channel_ != NULL);
693 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
695 int desired_bitrate = 128000;
696 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
698 EXPECT_TRUE(channel_->AddSendStream(
699 cricket::StreamParams::CreateLegacy(kSsrc1)));
701 int channel_num = voe_.GetLastChannel();
702 webrtc::CodecInst codec;
703 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
704 EXPECT_EQ(desired_bitrate, codec.rate);
707 // Test that bitrate cannot be set for CBR codecs.
708 // Bitrate is ignored if it is higher than the fixed bitrate.
709 // Bitrate less then the fixed bitrate is an error.
710 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
711 EXPECT_TRUE(SetupEngine());
712 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
714 webrtc::CodecInst codec;
715 int channel_num = voe_.GetLastChannel();
716 std::vector<cricket::AudioCodec> codecs;
718 // PCMU, default bitrate == 64000.
719 codecs.push_back(kPcmuCodec);
720 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
721 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
722 EXPECT_EQ(64000, codec.rate);
723 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
724 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
725 EXPECT_EQ(64000, codec.rate);
726 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
727 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
728 EXPECT_EQ(64000, codec.rate);
731 // Test that we apply codecs properly.
732 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
733 EXPECT_TRUE(SetupEngine());
734 int channel_num = voe_.GetLastChannel();
735 std::vector<cricket::AudioCodec> codecs;
736 codecs.push_back(kIsacCodec);
737 codecs.push_back(kPcmuCodec);
738 codecs.push_back(kRedCodec);
740 codecs[0].bitrate = 48000;
741 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
742 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
743 webrtc::CodecInst gcodec;
744 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
745 EXPECT_EQ(96, gcodec.pltype);
746 EXPECT_EQ(48000, gcodec.rate);
747 EXPECT_STREQ("ISAC", gcodec.plname);
748 EXPECT_FALSE(voe_.GetVAD(channel_num));
749 EXPECT_FALSE(voe_.GetRED(channel_num));
750 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
751 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
752 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
755 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
757 TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
758 EXPECT_TRUE(SetupEngine());
759 std::vector<cricket::AudioCodec> codecs;
760 codecs.push_back(kIsacCodec);
761 codecs.push_back(kPcmuCodec);
762 codecs.push_back(kRedCodec);
764 codecs[0].bitrate = 48000;
765 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
766 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
767 // Calling SetSendCodec again with same codec which is already set.
768 // In this case media channel shouldn't send codec to VoE.
769 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
770 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
773 // Test that if clockrate is not 48000 for opus, we fail.
774 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
775 EXPECT_TRUE(SetupEngine());
776 std::vector<cricket::AudioCodec> codecs;
777 codecs.push_back(kOpusCodec);
778 codecs[0].bitrate = 0;
779 codecs[0].clockrate = 50000;
780 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
783 // Test that if channels=0 for opus, we fail.
784 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
785 EXPECT_TRUE(SetupEngine());
786 std::vector<cricket::AudioCodec> codecs;
787 codecs.push_back(kOpusCodec);
788 codecs[0].bitrate = 0;
789 codecs[0].channels = 0;
790 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
793 // Test that if channels=0 for opus, we fail.
794 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
795 EXPECT_TRUE(SetupEngine());
796 std::vector<cricket::AudioCodec> codecs;
797 codecs.push_back(kOpusCodec);
798 codecs[0].bitrate = 0;
799 codecs[0].channels = 0;
800 codecs[0].params["stereo"] = "1";
801 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
804 // Test that if channel is 1 for opus and there's no stereo, we fail.
805 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
806 EXPECT_TRUE(SetupEngine());
807 std::vector<cricket::AudioCodec> codecs;
808 codecs.push_back(kOpusCodec);
809 codecs[0].bitrate = 0;
810 codecs[0].channels = 1;
811 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
814 // Test that if channel is 1 for opus and stereo=0, we fail.
815 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
816 EXPECT_TRUE(SetupEngine());
817 std::vector<cricket::AudioCodec> codecs;
818 codecs.push_back(kOpusCodec);
819 codecs[0].bitrate = 0;
820 codecs[0].channels = 1;
821 codecs[0].params["stereo"] = "0";
822 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
825 // Test that if channel is 1 for opus and stereo=1, we fail.
826 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
827 EXPECT_TRUE(SetupEngine());
828 std::vector<cricket::AudioCodec> codecs;
829 codecs.push_back(kOpusCodec);
830 codecs[0].bitrate = 0;
831 codecs[0].channels = 1;
832 codecs[0].params["stereo"] = "1";
833 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
836 // Test that with bitrate=0 and no stereo,
837 // channels and bitrate are 1 and 32000.
838 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
839 EXPECT_TRUE(SetupEngine());
840 int channel_num = voe_.GetLastChannel();
841 std::vector<cricket::AudioCodec> codecs;
842 codecs.push_back(kOpusCodec);
843 codecs[0].bitrate = 0;
844 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
845 webrtc::CodecInst gcodec;
846 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
847 EXPECT_STREQ("opus", gcodec.plname);
848 EXPECT_EQ(1, gcodec.channels);
849 EXPECT_EQ(32000, gcodec.rate);
852 // Test that with bitrate=0 and stereo=0,
853 // channels and bitrate are 1 and 32000.
854 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
855 EXPECT_TRUE(SetupEngine());
856 int channel_num = voe_.GetLastChannel();
857 std::vector<cricket::AudioCodec> codecs;
858 codecs.push_back(kOpusCodec);
859 codecs[0].bitrate = 0;
860 codecs[0].params["stereo"] = "0";
861 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
862 webrtc::CodecInst gcodec;
863 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
864 EXPECT_STREQ("opus", gcodec.plname);
865 EXPECT_EQ(1, gcodec.channels);
866 EXPECT_EQ(32000, gcodec.rate);
869 // Test that with bitrate=invalid and stereo=0,
870 // channels and bitrate are 1 and 32000.
871 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
872 EXPECT_TRUE(SetupEngine());
873 int channel_num = voe_.GetLastChannel();
874 std::vector<cricket::AudioCodec> codecs;
875 codecs.push_back(kOpusCodec);
876 codecs[0].params["stereo"] = "0";
877 webrtc::CodecInst gcodec;
879 // bitrate that's out of the range between 6000 and 510000 will be considered
880 // as invalid and ignored.
881 codecs[0].bitrate = 5999;
882 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
883 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
884 EXPECT_STREQ("opus", gcodec.plname);
885 EXPECT_EQ(1, gcodec.channels);
886 EXPECT_EQ(32000, gcodec.rate);
888 codecs[0].bitrate = 510001;
889 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
890 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
891 EXPECT_STREQ("opus", gcodec.plname);
892 EXPECT_EQ(1, gcodec.channels);
893 EXPECT_EQ(32000, gcodec.rate);
896 // Test that with bitrate=0 and stereo=1,
897 // channels and bitrate are 2 and 64000.
898 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
899 EXPECT_TRUE(SetupEngine());
900 int channel_num = voe_.GetLastChannel();
901 std::vector<cricket::AudioCodec> codecs;
902 codecs.push_back(kOpusCodec);
903 codecs[0].bitrate = 0;
904 codecs[0].params["stereo"] = "1";
905 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
906 webrtc::CodecInst gcodec;
907 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
908 EXPECT_STREQ("opus", gcodec.plname);
909 EXPECT_EQ(2, gcodec.channels);
910 EXPECT_EQ(64000, gcodec.rate);
913 // Test that with bitrate=invalid and stereo=1,
914 // channels and bitrate are 2 and 64000.
915 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
916 EXPECT_TRUE(SetupEngine());
917 int channel_num = voe_.GetLastChannel();
918 std::vector<cricket::AudioCodec> codecs;
919 codecs.push_back(kOpusCodec);
920 codecs[0].params["stereo"] = "1";
921 webrtc::CodecInst gcodec;
923 // bitrate that's out of the range between 6000 and 510000 will be considered
924 // as invalid and ignored.
925 codecs[0].bitrate = 5999;
926 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
927 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
928 EXPECT_STREQ("opus", gcodec.plname);
929 EXPECT_EQ(2, gcodec.channels);
930 EXPECT_EQ(64000, gcodec.rate);
932 codecs[0].bitrate = 510001;
933 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
934 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
935 EXPECT_STREQ("opus", gcodec.plname);
936 EXPECT_EQ(2, gcodec.channels);
937 EXPECT_EQ(64000, gcodec.rate);
940 // Test that with bitrate=N and stereo unset,
941 // channels and bitrate are 1 and N.
942 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
943 EXPECT_TRUE(SetupEngine());
944 int channel_num = voe_.GetLastChannel();
945 std::vector<cricket::AudioCodec> codecs;
946 codecs.push_back(kOpusCodec);
947 codecs[0].bitrate = 96000;
948 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
949 webrtc::CodecInst gcodec;
950 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
951 EXPECT_EQ(111, gcodec.pltype);
952 EXPECT_EQ(96000, gcodec.rate);
953 EXPECT_STREQ("opus", gcodec.plname);
954 EXPECT_EQ(1, gcodec.channels);
955 EXPECT_EQ(48000, gcodec.plfreq);
958 // Test that with bitrate=N and stereo=0,
959 // channels and bitrate are 1 and N.
960 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
961 EXPECT_TRUE(SetupEngine());
962 int channel_num = voe_.GetLastChannel();
963 std::vector<cricket::AudioCodec> codecs;
964 codecs.push_back(kOpusCodec);
965 codecs[0].bitrate = 30000;
966 codecs[0].params["stereo"] = "0";
967 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
968 webrtc::CodecInst gcodec;
969 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
970 EXPECT_EQ(1, gcodec.channels);
971 EXPECT_EQ(30000, gcodec.rate);
972 EXPECT_STREQ("opus", gcodec.plname);
975 // Test that with bitrate=N and without any parameters,
976 // channels and bitrate are 1 and N.
977 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
978 EXPECT_TRUE(SetupEngine());
979 int channel_num = voe_.GetLastChannel();
980 std::vector<cricket::AudioCodec> codecs;
981 codecs.push_back(kOpusCodec);
982 codecs[0].bitrate = 30000;
983 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
984 webrtc::CodecInst gcodec;
985 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
986 EXPECT_EQ(1, gcodec.channels);
987 EXPECT_EQ(30000, gcodec.rate);
988 EXPECT_STREQ("opus", gcodec.plname);
991 // Test that with bitrate=N and stereo=1,
992 // channels and bitrate are 2 and N.
993 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
994 EXPECT_TRUE(SetupEngine());
995 int channel_num = voe_.GetLastChannel();
996 std::vector<cricket::AudioCodec> codecs;
997 codecs.push_back(kOpusCodec);
998 codecs[0].bitrate = 30000;
999 codecs[0].params["stereo"] = "1";
1000 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1001 webrtc::CodecInst gcodec;
1002 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1003 EXPECT_EQ(2, gcodec.channels);
1004 EXPECT_EQ(30000, gcodec.rate);
1005 EXPECT_STREQ("opus", gcodec.plname);
1008 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1009 // Also test that the "maxaveragebitrate" can't be set to values outside the
1010 // range of 6000 and 510000
1011 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1012 EXPECT_TRUE(SetupEngine());
1013 int channel_num = voe_.GetLastChannel();
1014 std::vector<cricket::AudioCodec> codecs;
1015 codecs.push_back(kOpusCodec);
1016 codecs[0].bitrate = 30000;
1017 webrtc::CodecInst gcodec;
1019 // Ignore if less than 6000.
1020 codecs[0].params["maxaveragebitrate"] = "5999";
1021 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1022 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1023 EXPECT_EQ(30000, gcodec.rate);
1025 // Ignore if larger than 510000.
1026 codecs[0].params["maxaveragebitrate"] = "510001";
1027 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1028 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1029 EXPECT_EQ(30000, gcodec.rate);
1031 codecs[0].params["maxaveragebitrate"] = "200000";
1032 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1033 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1034 EXPECT_EQ(200000, gcodec.rate);
1037 // Test that we can enable NACK with opus as caller.
1038 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1039 EXPECT_TRUE(SetupEngine());
1040 int channel_num = voe_.GetLastChannel();
1041 std::vector<cricket::AudioCodec> codecs;
1042 codecs.push_back(kOpusCodec);
1043 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1044 cricket::kParamValueEmpty));
1045 EXPECT_FALSE(voe_.GetNACK(channel_num));
1046 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1047 EXPECT_TRUE(voe_.GetNACK(channel_num));
1050 // Test that we can enable NACK with opus as callee.
1051 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1052 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1053 channel_ = engine_.CreateChannel();
1054 EXPECT_TRUE(channel_ != NULL);
1056 int channel_num = voe_.GetLastChannel();
1057 std::vector<cricket::AudioCodec> codecs;
1058 codecs.push_back(kOpusCodec);
1059 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1060 cricket::kParamValueEmpty));
1061 EXPECT_FALSE(voe_.GetNACK(channel_num));
1062 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1063 EXPECT_FALSE(voe_.GetNACK(channel_num));
1065 EXPECT_TRUE(channel_->AddSendStream(
1066 cricket::StreamParams::CreateLegacy(kSsrc1)));
1067 EXPECT_TRUE(voe_.GetNACK(channel_num));
1070 // Test that we can enable NACK on receive streams.
1071 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1072 EXPECT_TRUE(SetupEngine());
1073 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1074 int channel_num1 = voe_.GetLastChannel();
1075 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1076 int channel_num2 = voe_.GetLastChannel();
1077 std::vector<cricket::AudioCodec> codecs;
1078 codecs.push_back(kOpusCodec);
1079 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1080 cricket::kParamValueEmpty));
1081 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1082 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1083 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1084 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1085 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1088 // Test that we can disable NACK.
1089 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1090 EXPECT_TRUE(SetupEngine());
1091 int channel_num = voe_.GetLastChannel();
1092 std::vector<cricket::AudioCodec> codecs;
1093 codecs.push_back(kOpusCodec);
1094 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1095 cricket::kParamValueEmpty));
1096 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1097 EXPECT_TRUE(voe_.GetNACK(channel_num));
1100 codecs.push_back(kOpusCodec);
1101 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1102 EXPECT_FALSE(voe_.GetNACK(channel_num));
1105 // Test that we can disable NACK on receive streams.
1106 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1107 EXPECT_TRUE(SetupEngine());
1108 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1109 int channel_num1 = voe_.GetLastChannel();
1110 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1111 int channel_num2 = voe_.GetLastChannel();
1112 std::vector<cricket::AudioCodec> codecs;
1113 codecs.push_back(kOpusCodec);
1114 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1115 cricket::kParamValueEmpty));
1116 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1117 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1118 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1121 codecs.push_back(kOpusCodec);
1122 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1123 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1124 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1127 // Test that NACK is enabled on a new receive stream.
1128 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1129 EXPECT_TRUE(SetupEngine());
1130 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1131 int channel_num = voe_.GetLastChannel();
1132 std::vector<cricket::AudioCodec> codecs;
1133 codecs.push_back(kIsacCodec);
1134 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1135 cricket::kParamValueEmpty));
1136 codecs.push_back(kCn16000Codec);
1137 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1138 EXPECT_TRUE(voe_.GetNACK(channel_num));
1140 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1141 channel_num = voe_.GetLastChannel();
1142 EXPECT_TRUE(voe_.GetNACK(channel_num));
1143 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1144 channel_num = voe_.GetLastChannel();
1145 EXPECT_TRUE(voe_.GetNACK(channel_num));
1148 #ifdef USE_WEBRTC_DEV_BRANCH
1149 // Test that without useinbandfec, Opus FEC is off.
1150 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
1151 EXPECT_TRUE(SetupEngine());
1152 int channel_num = voe_.GetLastChannel();
1153 std::vector<cricket::AudioCodec> codecs;
1154 codecs.push_back(kOpusCodec);
1155 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1156 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1159 // Test that with useinbandfec=0, Opus FEC is off.
1160 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
1161 EXPECT_TRUE(SetupEngine());
1162 int channel_num = voe_.GetLastChannel();
1163 std::vector<cricket::AudioCodec> codecs;
1164 codecs.push_back(kOpusCodec);
1165 codecs[0].bitrate = 0;
1166 codecs[0].params["useinbandfec"] = "0";
1167 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1168 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1169 webrtc::CodecInst gcodec;
1170 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1171 EXPECT_STREQ("opus", gcodec.plname);
1172 EXPECT_EQ(1, gcodec.channels);
1173 EXPECT_EQ(32000, gcodec.rate);
1176 // Test that with useinbandfec=1, Opus FEC is on.
1177 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
1178 EXPECT_TRUE(SetupEngine());
1179 int channel_num = voe_.GetLastChannel();
1180 std::vector<cricket::AudioCodec> codecs;
1181 codecs.push_back(kOpusCodec);
1182 codecs[0].bitrate = 0;
1183 codecs[0].params["useinbandfec"] = "1";
1184 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1185 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1186 webrtc::CodecInst gcodec;
1187 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1188 EXPECT_STREQ("opus", gcodec.plname);
1189 EXPECT_EQ(1, gcodec.channels);
1190 EXPECT_EQ(32000, gcodec.rate);
1193 // Test that with useinbandfec=1, stereo=1, Opus FEC is on.
1194 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
1195 EXPECT_TRUE(SetupEngine());
1196 int channel_num = voe_.GetLastChannel();
1197 std::vector<cricket::AudioCodec> codecs;
1198 codecs.push_back(kOpusCodec);
1199 codecs[0].bitrate = 0;
1200 codecs[0].params["stereo"] = "1";
1201 codecs[0].params["useinbandfec"] = "1";
1202 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1203 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1204 webrtc::CodecInst gcodec;
1205 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1206 EXPECT_STREQ("opus", gcodec.plname);
1207 EXPECT_EQ(2, gcodec.channels);
1208 EXPECT_EQ(64000, gcodec.rate);
1211 // Test that with non-Opus, codec FEC is off.
1212 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
1213 EXPECT_TRUE(SetupEngine());
1214 int channel_num = voe_.GetLastChannel();
1215 std::vector<cricket::AudioCodec> codecs;
1216 codecs.push_back(kIsacCodec);
1217 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1218 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1221 // Test the with non-Opus, even if useinbandfec=1, FEC is off.
1222 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1223 EXPECT_TRUE(SetupEngine());
1224 int channel_num = voe_.GetLastChannel();
1225 std::vector<cricket::AudioCodec> codecs;
1226 codecs.push_back(kIsacCodec);
1227 codecs[0].params["useinbandfec"] = "1";
1228 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1229 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1232 // Test that Opus FEC status can be changed.
1233 TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1234 EXPECT_TRUE(SetupEngine());
1235 int channel_num = voe_.GetLastChannel();
1236 std::vector<cricket::AudioCodec> codecs;
1237 codecs.push_back(kOpusCodec);
1238 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1239 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1240 codecs[0].params["useinbandfec"] = "1";
1241 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1242 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1245 // Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1246 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1247 EXPECT_TRUE(SetupEngine());
1248 int channel_num = voe_.GetLastChannel();
1249 std::vector<cricket::AudioCodec> codecs;
1250 codecs.push_back(kOpusCodec);
1251 codecs[0].bitrate = 0;
1252 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1253 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1254 EXPECT_EQ(cricket::kOpusBandwidthNb,
1255 voe_.GetMaxEncodingBandwidth(channel_num));
1256 webrtc::CodecInst gcodec;
1257 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1258 EXPECT_STREQ("opus", gcodec.plname);
1259 // TODO(minyue): Default bit rate is not but can in future be affected by
1260 // kCodecParamMaxPlaybackRate.
1261 EXPECT_EQ(32000, gcodec.rate);
1264 // Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1265 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1266 EXPECT_TRUE(SetupEngine());
1267 int channel_num = voe_.GetLastChannel();
1268 std::vector<cricket::AudioCodec> codecs;
1269 codecs.push_back(kOpusCodec);
1270 codecs[0].bitrate = 0;
1271 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1272 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1273 EXPECT_EQ(cricket::kOpusBandwidthMb,
1274 voe_.GetMaxEncodingBandwidth(channel_num));
1275 webrtc::CodecInst gcodec;
1276 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1277 EXPECT_STREQ("opus", gcodec.plname);
1278 // TODO(minyue): Default bit rate is not but can in future be affected by
1279 // kCodecParamMaxPlaybackRate.
1280 EXPECT_EQ(32000, gcodec.rate);
1283 // Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1284 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1285 EXPECT_TRUE(SetupEngine());
1286 int channel_num = voe_.GetLastChannel();
1287 std::vector<cricket::AudioCodec> codecs;
1288 codecs.push_back(kOpusCodec);
1289 codecs[0].bitrate = 0;
1290 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1291 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1292 EXPECT_EQ(cricket::kOpusBandwidthWb,
1293 voe_.GetMaxEncodingBandwidth(channel_num));
1294 webrtc::CodecInst gcodec;
1295 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1296 EXPECT_STREQ("opus", gcodec.plname);
1297 // TODO(minyue): Default bit rate is not but can in future be affected by
1298 // kCodecParamMaxPlaybackRate.
1299 EXPECT_EQ(32000, gcodec.rate);
1302 // Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1303 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1304 EXPECT_TRUE(SetupEngine());
1305 int channel_num = voe_.GetLastChannel();
1306 std::vector<cricket::AudioCodec> codecs;
1307 codecs.push_back(kOpusCodec);
1308 codecs[0].bitrate = 0;
1309 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1310 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1311 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1312 voe_.GetMaxEncodingBandwidth(channel_num));
1313 webrtc::CodecInst gcodec;
1314 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1315 EXPECT_STREQ("opus", gcodec.plname);
1316 // TODO(minyue): Default bit rate is not but can in future be affected by
1317 // kCodecParamMaxPlaybackRate.
1318 EXPECT_EQ(32000, gcodec.rate);
1321 // Test 24000 < maxplaybackrate triggers Opus full band mode.
1322 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1323 EXPECT_TRUE(SetupEngine());
1324 int channel_num = voe_.GetLastChannel();
1325 std::vector<cricket::AudioCodec> codecs;
1326 codecs.push_back(kOpusCodec);
1327 codecs[0].bitrate = 0;
1328 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1329 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1330 EXPECT_EQ(cricket::kOpusBandwidthFb,
1331 voe_.GetMaxEncodingBandwidth(channel_num));
1332 webrtc::CodecInst gcodec;
1333 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1334 EXPECT_STREQ("opus", gcodec.plname);
1335 // TODO(minyue): Default bit rate is not but can in future be affected by
1336 // kCodecParamMaxPlaybackRate.
1337 EXPECT_EQ(32000, gcodec.rate);
1340 // Test Opus that without maxplaybackrate, default playback rate is used.
1341 TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1342 EXPECT_TRUE(SetupEngine());
1343 int channel_num = voe_.GetLastChannel();
1344 std::vector<cricket::AudioCodec> codecs;
1345 codecs.push_back(kOpusCodec);
1346 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1347 EXPECT_EQ(cricket::kOpusBandwidthFb,
1348 voe_.GetMaxEncodingBandwidth(channel_num));
1351 // Test the with non-Opus, maxplaybackrate has no effect.
1352 TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1353 EXPECT_TRUE(SetupEngine());
1354 int channel_num = voe_.GetLastChannel();
1355 std::vector<cricket::AudioCodec> codecs;
1356 codecs.push_back(kIsacCodec);
1357 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1358 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1359 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1362 // Test maxplaybackrate can be set on two streams.
1363 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1364 EXPECT_TRUE(SetupEngine());
1365 int channel_num = voe_.GetLastChannel();
1366 std::vector<cricket::AudioCodec> codecs;
1367 codecs.push_back(kOpusCodec);
1368 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1369 // Default bandwidth is 24000.
1370 EXPECT_EQ(cricket::kOpusBandwidthFb,
1371 voe_.GetMaxEncodingBandwidth(channel_num));
1373 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1375 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1376 EXPECT_EQ(cricket::kOpusBandwidthNb,
1377 voe_.GetMaxEncodingBandwidth(channel_num));
1379 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1380 channel_num = voe_.GetLastChannel();
1381 EXPECT_EQ(cricket::kOpusBandwidthNb,
1382 voe_.GetMaxEncodingBandwidth(channel_num));
1384 #endif // USE_WEBRTC_DEV_BRANCH
1386 // Test that we can apply CELT with stereo mode but fail with mono mode.
1387 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1388 EXPECT_TRUE(SetupEngine());
1389 int channel_num = voe_.GetLastChannel();
1390 std::vector<cricket::AudioCodec> codecs;
1391 codecs.push_back(kCeltCodec);
1392 codecs.push_back(kIsacCodec);
1394 codecs[0].channels = 2;
1395 codecs[0].bitrate = 96000;
1396 codecs[1].bitrate = 64000;
1397 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1398 webrtc::CodecInst gcodec;
1399 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1400 EXPECT_EQ(96, gcodec.pltype);
1401 EXPECT_EQ(96000, gcodec.rate);
1402 EXPECT_EQ(2, gcodec.channels);
1403 EXPECT_STREQ("CELT", gcodec.plname);
1404 // Doesn't support mono, expect it to fall back to the next codec in the list.
1405 codecs[0].channels = 1;
1406 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1407 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1408 EXPECT_EQ(103, gcodec.pltype);
1409 EXPECT_EQ(1, gcodec.channels);
1410 EXPECT_EQ(64000, gcodec.rate);
1411 EXPECT_STREQ("ISAC", gcodec.plname);
1414 // Test that we can switch back and forth between CELT and ISAC with CN.
1415 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1416 EXPECT_TRUE(SetupEngine());
1417 int channel_num = voe_.GetLastChannel();
1418 std::vector<cricket::AudioCodec> celt_codecs;
1419 celt_codecs.push_back(kCeltCodec);
1420 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1421 webrtc::CodecInst gcodec;
1422 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1423 EXPECT_EQ(110, gcodec.pltype);
1424 EXPECT_STREQ("CELT", gcodec.plname);
1426 std::vector<cricket::AudioCodec> isac_codecs;
1427 isac_codecs.push_back(kIsacCodec);
1428 isac_codecs.push_back(kCn16000Codec);
1429 isac_codecs.push_back(kCeltCodec);
1430 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1431 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1432 EXPECT_EQ(103, gcodec.pltype);
1433 EXPECT_STREQ("ISAC", gcodec.plname);
1435 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1436 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1437 EXPECT_EQ(110, gcodec.pltype);
1438 EXPECT_STREQ("CELT", gcodec.plname);
1441 // Test that we handle various ways of specifying bitrate.
1442 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1443 EXPECT_TRUE(SetupEngine());
1444 int channel_num = voe_.GetLastChannel();
1445 std::vector<cricket::AudioCodec> codecs;
1446 codecs.push_back(kIsacCodec); // bitrate == 32000
1447 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1448 webrtc::CodecInst gcodec;
1449 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1450 EXPECT_EQ(103, gcodec.pltype);
1451 EXPECT_STREQ("ISAC", gcodec.plname);
1452 EXPECT_EQ(32000, gcodec.rate);
1454 codecs[0].bitrate = 0; // bitrate == default
1455 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1456 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1457 EXPECT_EQ(103, gcodec.pltype);
1458 EXPECT_STREQ("ISAC", gcodec.plname);
1459 EXPECT_EQ(-1, gcodec.rate);
1461 codecs[0].bitrate = 28000; // bitrate == 28000
1462 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1463 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1464 EXPECT_EQ(103, gcodec.pltype);
1465 EXPECT_STREQ("ISAC", gcodec.plname);
1466 EXPECT_EQ(28000, gcodec.rate);
1468 codecs[0] = kPcmuCodec; // bitrate == 64000
1469 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1470 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1471 EXPECT_EQ(0, gcodec.pltype);
1472 EXPECT_STREQ("PCMU", gcodec.plname);
1473 EXPECT_EQ(64000, gcodec.rate);
1475 codecs[0].bitrate = 0; // bitrate == default
1476 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1477 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1478 EXPECT_EQ(0, gcodec.pltype);
1479 EXPECT_STREQ("PCMU", gcodec.plname);
1480 EXPECT_EQ(64000, gcodec.rate);
1482 codecs[0] = kOpusCodec;
1483 codecs[0].bitrate = 0; // bitrate == default
1484 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1485 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1486 EXPECT_EQ(111, gcodec.pltype);
1487 EXPECT_STREQ("opus", gcodec.plname);
1488 EXPECT_EQ(32000, gcodec.rate);
1491 // Test that we fail if no codecs are specified.
1492 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1493 EXPECT_TRUE(SetupEngine());
1494 std::vector<cricket::AudioCodec> codecs;
1495 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1498 // Test that we can set send codecs even with telephone-event codec as the first
1500 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1501 EXPECT_TRUE(SetupEngine());
1502 int channel_num = voe_.GetLastChannel();
1503 std::vector<cricket::AudioCodec> codecs;
1504 codecs.push_back(kTelephoneEventCodec);
1505 codecs.push_back(kIsacCodec);
1506 codecs.push_back(kPcmuCodec);
1507 codecs[0].id = 98; // DTMF
1509 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1510 webrtc::CodecInst gcodec;
1511 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1512 EXPECT_EQ(96, gcodec.pltype);
1513 EXPECT_STREQ("ISAC", gcodec.plname);
1514 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1517 // Test that we can set send codecs even with CN codec as the first
1519 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1520 EXPECT_TRUE(SetupEngine());
1521 int channel_num = voe_.GetLastChannel();
1522 std::vector<cricket::AudioCodec> codecs;
1523 codecs.push_back(kCn16000Codec);
1524 codecs.push_back(kIsacCodec);
1525 codecs.push_back(kPcmuCodec);
1526 codecs[0].id = 98; // wideband CN
1528 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1529 webrtc::CodecInst gcodec;
1530 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1531 EXPECT_EQ(96, gcodec.pltype);
1532 EXPECT_STREQ("ISAC", gcodec.plname);
1533 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1536 // Test that we set VAD and DTMF types correctly as caller.
1537 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1538 EXPECT_TRUE(SetupEngine());
1539 int channel_num = voe_.GetLastChannel();
1540 std::vector<cricket::AudioCodec> codecs;
1541 codecs.push_back(kIsacCodec);
1542 codecs.push_back(kPcmuCodec);
1543 // TODO(juberti): cn 32000
1544 codecs.push_back(kCn16000Codec);
1545 codecs.push_back(kCn8000Codec);
1546 codecs.push_back(kTelephoneEventCodec);
1547 codecs.push_back(kRedCodec);
1549 codecs[2].id = 97; // wideband CN
1550 codecs[4].id = 98; // DTMF
1551 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1552 webrtc::CodecInst gcodec;
1553 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1554 EXPECT_EQ(96, gcodec.pltype);
1555 EXPECT_STREQ("ISAC", gcodec.plname);
1556 EXPECT_TRUE(voe_.GetVAD(channel_num));
1557 EXPECT_FALSE(voe_.GetRED(channel_num));
1558 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1559 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1560 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1563 // Test that we set VAD and DTMF types correctly as callee.
1564 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1565 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1566 channel_ = engine_.CreateChannel();
1567 EXPECT_TRUE(channel_ != NULL);
1569 int channel_num = voe_.GetLastChannel();
1570 std::vector<cricket::AudioCodec> codecs;
1571 codecs.push_back(kIsacCodec);
1572 codecs.push_back(kPcmuCodec);
1573 // TODO(juberti): cn 32000
1574 codecs.push_back(kCn16000Codec);
1575 codecs.push_back(kCn8000Codec);
1576 codecs.push_back(kTelephoneEventCodec);
1577 codecs.push_back(kRedCodec);
1579 codecs[2].id = 97; // wideband CN
1580 codecs[4].id = 98; // DTMF
1581 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1582 EXPECT_TRUE(channel_->AddSendStream(
1583 cricket::StreamParams::CreateLegacy(kSsrc1)));
1585 webrtc::CodecInst gcodec;
1586 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1587 EXPECT_EQ(96, gcodec.pltype);
1588 EXPECT_STREQ("ISAC", gcodec.plname);
1589 EXPECT_TRUE(voe_.GetVAD(channel_num));
1590 EXPECT_FALSE(voe_.GetRED(channel_num));
1591 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1592 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1593 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1596 // Test that we only apply VAD if we have a CN codec that matches the
1597 // send codec clockrate.
1598 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1599 EXPECT_TRUE(SetupEngine());
1600 int channel_num = voe_.GetLastChannel();
1601 std::vector<cricket::AudioCodec> codecs;
1602 // Set ISAC(16K) and CN(16K). VAD should be activated.
1603 codecs.push_back(kIsacCodec);
1604 codecs.push_back(kCn16000Codec);
1606 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1607 webrtc::CodecInst gcodec;
1608 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1609 EXPECT_STREQ("ISAC", gcodec.plname);
1610 EXPECT_TRUE(voe_.GetVAD(channel_num));
1611 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1612 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1613 codecs[0] = kPcmuCodec;
1614 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1615 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1616 EXPECT_STREQ("PCMU", gcodec.plname);
1617 EXPECT_FALSE(voe_.GetVAD(channel_num));
1618 // Set PCMU(8K) and CN(8K). VAD should be activated.
1619 codecs[1] = kCn8000Codec;
1620 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1621 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1622 EXPECT_STREQ("PCMU", gcodec.plname);
1623 EXPECT_TRUE(voe_.GetVAD(channel_num));
1624 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1625 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1626 codecs[0] = kIsacCodec;
1627 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1628 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1629 EXPECT_STREQ("ISAC", gcodec.plname);
1630 EXPECT_FALSE(voe_.GetVAD(channel_num));
1633 // Test that we perform case-insensitive matching of codec names.
1634 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1635 EXPECT_TRUE(SetupEngine());
1636 int channel_num = voe_.GetLastChannel();
1637 std::vector<cricket::AudioCodec> codecs;
1638 codecs.push_back(kIsacCodec);
1639 codecs.push_back(kPcmuCodec);
1640 codecs.push_back(kCn16000Codec);
1641 codecs.push_back(kCn8000Codec);
1642 codecs.push_back(kTelephoneEventCodec);
1643 codecs.push_back(kRedCodec);
1644 codecs[0].name = "iSaC";
1646 codecs[2].id = 97; // wideband CN
1647 codecs[4].id = 98; // DTMF
1648 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1649 webrtc::CodecInst gcodec;
1650 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1651 EXPECT_EQ(96, gcodec.pltype);
1652 EXPECT_STREQ("ISAC", gcodec.plname);
1653 EXPECT_TRUE(voe_.GetVAD(channel_num));
1654 EXPECT_FALSE(voe_.GetRED(channel_num));
1655 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1656 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1657 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1660 // Test that we set up RED correctly as caller.
1661 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1662 EXPECT_TRUE(SetupEngine());
1663 int channel_num = voe_.GetLastChannel();
1664 std::vector<cricket::AudioCodec> codecs;
1665 codecs.push_back(kRedCodec);
1666 codecs.push_back(kIsacCodec);
1667 codecs.push_back(kPcmuCodec);
1669 codecs[0].params[""] = "96/96";
1671 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1672 webrtc::CodecInst gcodec;
1673 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1674 EXPECT_EQ(96, gcodec.pltype);
1675 EXPECT_STREQ("ISAC", gcodec.plname);
1676 EXPECT_TRUE(voe_.GetRED(channel_num));
1677 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1680 // Test that we set up RED correctly as callee.
1681 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1682 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1683 channel_ = engine_.CreateChannel();
1684 EXPECT_TRUE(channel_ != NULL);
1686 int channel_num = voe_.GetLastChannel();
1687 std::vector<cricket::AudioCodec> codecs;
1688 codecs.push_back(kRedCodec);
1689 codecs.push_back(kIsacCodec);
1690 codecs.push_back(kPcmuCodec);
1692 codecs[0].params[""] = "96/96";
1694 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1695 EXPECT_TRUE(channel_->AddSendStream(
1696 cricket::StreamParams::CreateLegacy(kSsrc1)));
1697 webrtc::CodecInst gcodec;
1698 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1699 EXPECT_EQ(96, gcodec.pltype);
1700 EXPECT_STREQ("ISAC", gcodec.plname);
1701 EXPECT_TRUE(voe_.GetRED(channel_num));
1702 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1705 // Test that we set up RED correctly if params are omitted.
1706 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1707 EXPECT_TRUE(SetupEngine());
1708 int channel_num = voe_.GetLastChannel();
1709 std::vector<cricket::AudioCodec> codecs;
1710 codecs.push_back(kRedCodec);
1711 codecs.push_back(kIsacCodec);
1712 codecs.push_back(kPcmuCodec);
1715 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1716 webrtc::CodecInst gcodec;
1717 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1718 EXPECT_EQ(96, gcodec.pltype);
1719 EXPECT_STREQ("ISAC", gcodec.plname);
1720 EXPECT_TRUE(voe_.GetRED(channel_num));
1721 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1724 // Test that we ignore RED if the parameters aren't named the way we expect.
1725 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1726 EXPECT_TRUE(SetupEngine());
1727 int channel_num = voe_.GetLastChannel();
1728 std::vector<cricket::AudioCodec> codecs;
1729 codecs.push_back(kRedCodec);
1730 codecs.push_back(kIsacCodec);
1731 codecs.push_back(kPcmuCodec);
1733 codecs[0].params["ABC"] = "96/96";
1735 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1736 webrtc::CodecInst gcodec;
1737 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1738 EXPECT_EQ(96, gcodec.pltype);
1739 EXPECT_STREQ("ISAC", gcodec.plname);
1740 EXPECT_FALSE(voe_.GetRED(channel_num));
1743 // Test that we ignore RED if it uses different primary/secondary encoding.
1744 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1745 EXPECT_TRUE(SetupEngine());
1746 int channel_num = voe_.GetLastChannel();
1747 std::vector<cricket::AudioCodec> codecs;
1748 codecs.push_back(kRedCodec);
1749 codecs.push_back(kIsacCodec);
1750 codecs.push_back(kPcmuCodec);
1752 codecs[0].params[""] = "96/0";
1754 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1755 webrtc::CodecInst gcodec;
1756 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1757 EXPECT_EQ(96, gcodec.pltype);
1758 EXPECT_STREQ("ISAC", gcodec.plname);
1759 EXPECT_FALSE(voe_.GetRED(channel_num));
1762 // Test that we ignore RED if it uses more than 2 encodings.
1763 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1764 EXPECT_TRUE(SetupEngine());
1765 int channel_num = voe_.GetLastChannel();
1766 std::vector<cricket::AudioCodec> codecs;
1767 codecs.push_back(kRedCodec);
1768 codecs.push_back(kIsacCodec);
1769 codecs.push_back(kPcmuCodec);
1771 codecs[0].params[""] = "96/96/96";
1773 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1774 webrtc::CodecInst gcodec;
1775 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1776 EXPECT_EQ(96, gcodec.pltype);
1777 EXPECT_STREQ("ISAC", gcodec.plname);
1778 EXPECT_FALSE(voe_.GetRED(channel_num));
1781 // Test that we ignore RED if it has bogus codec ids.
1782 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1783 EXPECT_TRUE(SetupEngine());
1784 int channel_num = voe_.GetLastChannel();
1785 std::vector<cricket::AudioCodec> codecs;
1786 codecs.push_back(kRedCodec);
1787 codecs.push_back(kIsacCodec);
1788 codecs.push_back(kPcmuCodec);
1790 codecs[0].params[""] = "ABC/ABC";
1792 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1793 webrtc::CodecInst gcodec;
1794 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1795 EXPECT_EQ(96, gcodec.pltype);
1796 EXPECT_STREQ("ISAC", gcodec.plname);
1797 EXPECT_FALSE(voe_.GetRED(channel_num));
1800 // Test that we ignore RED if it refers to a codec that is not present.
1801 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1802 EXPECT_TRUE(SetupEngine());
1803 int channel_num = voe_.GetLastChannel();
1804 std::vector<cricket::AudioCodec> codecs;
1805 codecs.push_back(kRedCodec);
1806 codecs.push_back(kIsacCodec);
1807 codecs.push_back(kPcmuCodec);
1809 codecs[0].params[""] = "97/97";
1811 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1812 webrtc::CodecInst gcodec;
1813 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1814 EXPECT_EQ(96, gcodec.pltype);
1815 EXPECT_STREQ("ISAC", gcodec.plname);
1816 EXPECT_FALSE(voe_.GetRED(channel_num));
1819 // Test support for audio level header extension.
1820 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1821 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1823 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1824 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1827 // Test support for absolute send time header extension.
1828 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1829 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1831 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1832 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1835 // Test that we can create a channel and start sending/playing out on it.
1836 TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1837 EXPECT_TRUE(SetupEngine());
1838 int channel_num = voe_.GetLastChannel();
1839 std::vector<cricket::AudioCodec> codecs;
1840 codecs.push_back(kPcmuCodec);
1841 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1842 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1843 EXPECT_TRUE(voe_.GetSend(channel_num));
1844 EXPECT_TRUE(channel_->SetPlayout(true));
1845 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1846 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1847 EXPECT_FALSE(voe_.GetSend(channel_num));
1848 EXPECT_TRUE(channel_->SetPlayout(false));
1849 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1852 // Test that we can add and remove send streams.
1853 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1854 SetupForMultiSendStream();
1856 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1858 // Set the global state for sending.
1859 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1861 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1862 EXPECT_TRUE(channel_->AddSendStream(
1863 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1865 // Verify that we are in a sending state for all the created streams.
1866 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1867 EXPECT_TRUE(voe_.GetSend(channel_num));
1870 // Remove the first send channel, which is the default channel. It will only
1871 // recycle the default channel but not delete it.
1872 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1873 // Stream should already be Removed from the send stream list.
1874 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1875 // But the default still exists.
1876 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1878 // Delete the rest of send channel streams.
1879 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1880 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1881 // Stream should already be deleted.
1882 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1883 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1887 // Test SetSendCodecs correctly configure the codecs in all send streams.
1888 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1889 SetupForMultiSendStream();
1891 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1892 // Create send streams.
1893 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1894 EXPECT_TRUE(channel_->AddSendStream(
1895 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1898 std::vector<cricket::AudioCodec> codecs;
1899 // Set ISAC(16K) and CN(16K). VAD should be activated.
1900 codecs.push_back(kIsacCodec);
1901 codecs.push_back(kCn16000Codec);
1903 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1905 // Verify ISAC and VAD are corrected configured on all send channels.
1906 webrtc::CodecInst gcodec;
1907 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1908 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1909 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1910 EXPECT_STREQ("ISAC", gcodec.plname);
1911 EXPECT_TRUE(voe_.GetVAD(channel_num));
1912 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1915 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1916 codecs[0] = kPcmuCodec;
1917 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1918 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1919 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1920 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1921 EXPECT_STREQ("PCMU", gcodec.plname);
1922 EXPECT_FALSE(voe_.GetVAD(channel_num));
1926 // Test we can SetSend on all send streams correctly.
1927 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1928 SetupForMultiSendStream();
1930 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1931 // Create the send channels and they should be a SEND_NOTHING date.
1932 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1933 EXPECT_TRUE(channel_->AddSendStream(
1934 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1935 int channel_num = voe_.GetLastChannel();
1936 EXPECT_FALSE(voe_.GetSend(channel_num));
1939 // Set the global state for starting sending.
1940 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1941 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1942 // Verify that we are in a sending state for all the send streams.
1943 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1944 EXPECT_TRUE(voe_.GetSend(channel_num));
1947 // Set the global state for stopping sending.
1948 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1949 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1950 // Verify that we are in a stop state for all the send streams.
1951 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1952 EXPECT_FALSE(voe_.GetSend(channel_num));
1956 // Test we can set the correct statistics on all send streams.
1957 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1958 SetupForMultiSendStream();
1960 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1961 // Create send streams.
1962 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1963 EXPECT_TRUE(channel_->AddSendStream(
1964 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1966 // Create a receive stream to check that none of the send streams end up in
1967 // the receive stream stats.
1968 EXPECT_TRUE(channel_->AddRecvStream(
1969 cricket::StreamParams::CreateLegacy(kSsrc2)));
1970 // We need send codec to be set to get all stats.
1971 std::vector<cricket::AudioCodec> codecs;
1972 codecs.push_back(kPcmuCodec);
1973 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1974 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1976 cricket::VoiceMediaInfo info;
1977 EXPECT_EQ(true, channel_->GetStats(&info));
1978 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1980 // Verify the statistic information is correct.
1981 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1982 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
1983 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1984 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1985 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1986 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1987 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1988 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1989 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1990 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1991 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1994 EXPECT_EQ(0u, info.receivers.size());
1995 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1996 EXPECT_EQ(true, channel_->GetStats(&info));
1998 EXPECT_EQ(1u, info.receivers.size());
1999 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2000 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2001 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2002 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2003 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
2006 // Test that we can add and remove receive streams, and do proper send/playout.
2007 // We can receive on multiple streams while sending one stream.
2008 TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
2009 EXPECT_TRUE(SetupEngine());
2010 int channel_num1 = voe_.GetLastChannel();
2012 // Start playout on the default channel.
2013 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2014 EXPECT_TRUE(channel_->SetPlayout(true));
2015 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2017 // Adding another stream should disable playout on the default channel.
2018 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2019 int channel_num2 = voe_.GetLastChannel();
2020 std::vector<cricket::AudioCodec> codecs;
2021 codecs.push_back(kPcmuCodec);
2022 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2023 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2024 EXPECT_TRUE(voe_.GetSend(channel_num1));
2025 EXPECT_FALSE(voe_.GetSend(channel_num2));
2027 // Make sure only the new channel is played out.
2028 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2029 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2031 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2032 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2033 int channel_num3 = voe_.GetLastChannel();
2034 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2035 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2036 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2037 EXPECT_FALSE(voe_.GetSend(channel_num3));
2040 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2041 EXPECT_FALSE(voe_.GetSend(channel_num1));
2042 EXPECT_FALSE(voe_.GetSend(channel_num2));
2043 EXPECT_FALSE(voe_.GetSend(channel_num3));
2046 EXPECT_TRUE(channel_->SetPlayout(false));
2047 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2048 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2049 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2051 // Restart playout and make sure the default channel still is not played out.
2052 EXPECT_TRUE(channel_->SetPlayout(true));
2053 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2054 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2055 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2057 // Now remove the new streams and verify that the default channel is
2058 // played out again.
2059 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2060 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2062 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2065 // Test that we can set the devices to use.
2066 TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2067 EXPECT_TRUE(SetupEngine());
2068 int channel_num = voe_.GetLastChannel();
2069 std::vector<cricket::AudioCodec> codecs;
2070 codecs.push_back(kPcmuCodec);
2071 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2073 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2074 cricket::kFakeDefaultDeviceId);
2075 cricket::Device dev(cricket::kFakeDeviceName,
2076 cricket::kFakeDeviceId);
2078 // Test SetDevices() while not sending or playing.
2079 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2081 // Test SetDevices() while sending and playing.
2082 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2083 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2084 EXPECT_TRUE(channel_->SetPlayout(true));
2085 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2086 EXPECT_TRUE(voe_.GetSend(channel_num));
2087 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2089 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2091 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2092 EXPECT_TRUE(voe_.GetSend(channel_num));
2093 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2095 // Test that failure to open newly selected devices does not prevent opening
2097 voe_.set_fail_start_recording_microphone(true);
2098 voe_.set_playout_fail_channel(channel_num);
2099 voe_.set_send_fail_channel(channel_num);
2101 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2103 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2104 EXPECT_FALSE(voe_.GetSend(channel_num));
2105 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2107 voe_.set_fail_start_recording_microphone(false);
2108 voe_.set_playout_fail_channel(-1);
2109 voe_.set_send_fail_channel(-1);
2111 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2113 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2114 EXPECT_TRUE(voe_.GetSend(channel_num));
2115 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2118 // Test that we can set the devices to use even if we failed to
2119 // open the initial ones.
2120 TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2121 EXPECT_TRUE(SetupEngine());
2122 int channel_num = voe_.GetLastChannel();
2123 std::vector<cricket::AudioCodec> codecs;
2124 codecs.push_back(kPcmuCodec);
2125 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2127 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2128 cricket::kFakeDefaultDeviceId);
2129 cricket::Device dev(cricket::kFakeDeviceName,
2130 cricket::kFakeDeviceId);
2132 // Test that failure to open devices selected before starting
2133 // send/play does not prevent opening newly selected ones after that.
2134 voe_.set_fail_start_recording_microphone(true);
2135 voe_.set_playout_fail_channel(channel_num);
2136 voe_.set_send_fail_channel(channel_num);
2138 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2140 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2141 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2142 EXPECT_FALSE(channel_->SetPlayout(true));
2143 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2144 EXPECT_FALSE(voe_.GetSend(channel_num));
2145 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2147 voe_.set_fail_start_recording_microphone(false);
2148 voe_.set_playout_fail_channel(-1);
2149 voe_.set_send_fail_channel(-1);
2151 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2153 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2154 EXPECT_TRUE(voe_.GetSend(channel_num));
2155 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2158 // Test that we can create a channel configured for multi-point conferences,
2159 // and start sending/playing out on it.
2160 TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2161 EXPECT_TRUE(SetupEngine());
2162 int channel_num = voe_.GetLastChannel();
2163 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2164 std::vector<cricket::AudioCodec> codecs;
2165 codecs.push_back(kPcmuCodec);
2166 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2167 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2168 EXPECT_TRUE(voe_.GetSend(channel_num));
2171 // Test that we can create a channel configured for Codian bridges,
2172 // and start sending/playing out on it.
2173 TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2174 EXPECT_TRUE(SetupEngine());
2175 int channel_num = voe_.GetLastChannel();
2176 webrtc::AgcConfig agc_config;
2177 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2178 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2179 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2180 std::vector<cricket::AudioCodec> codecs;
2181 codecs.push_back(kPcmuCodec);
2182 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2183 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2184 EXPECT_TRUE(voe_.GetSend(channel_num));
2185 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2186 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2187 EXPECT_TRUE(channel_->SetPlayout(true));
2188 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2189 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2190 EXPECT_FALSE(voe_.GetSend(channel_num));
2191 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2192 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2193 EXPECT_TRUE(channel_->SetPlayout(false));
2194 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2197 TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2198 EXPECT_TRUE(SetupEngine());
2199 webrtc::AgcConfig agc_config;
2200 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2201 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2203 cricket::AudioOptions options;
2204 options.tx_agc_target_dbov.Set(3);
2205 options.tx_agc_digital_compression_gain.Set(9);
2206 options.tx_agc_limiter.Set(true);
2207 options.auto_gain_control.Set(true);
2208 EXPECT_TRUE(engine_.SetOptions(options));
2210 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2211 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2212 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2213 EXPECT_TRUE(agc_config.limiterEnable);
2215 // Check interaction with adjust_agc_delta. Both should be respected, for
2216 // backwards compatibility.
2217 options.adjust_agc_delta.Set(-10);
2218 EXPECT_TRUE(engine_.SetOptions(options));
2220 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2221 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2224 TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2225 EXPECT_TRUE(SetupEngine());
2226 int channel_num = voe_.GetLastChannel();
2227 cricket::AudioOptions options;
2228 options.rx_agc_target_dbov.Set(6);
2229 options.rx_agc_digital_compression_gain.Set(0);
2230 options.rx_agc_limiter.Set(true);
2231 options.rx_auto_gain_control.Set(true);
2232 EXPECT_TRUE(channel_->SetOptions(options));
2234 webrtc::AgcConfig agc_config;
2235 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2236 channel_num, agc_config));
2237 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2238 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2239 EXPECT_TRUE(agc_config.limiterEnable);
2242 TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2243 EXPECT_TRUE(SetupEngine());
2244 cricket::AudioOptions options;
2245 options.recording_sample_rate.Set(48000u);
2246 options.playout_sample_rate.Set(44100u);
2247 EXPECT_TRUE(engine_.SetOptions(options));
2249 unsigned int recording_sample_rate, playout_sample_rate;
2250 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2251 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2252 EXPECT_EQ(48000u, recording_sample_rate);
2253 EXPECT_EQ(44100u, playout_sample_rate);
2256 TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2257 EXPECT_TRUE(SetupEngine());
2258 engine_.SetLogging(rtc::LS_INFO, "");
2261 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2263 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2265 webrtc::kTraceError | webrtc::kTraceCritical,
2266 static_cast<int>(trace_wrapper_->filter_));
2267 // Now set it explicitly
2268 std::string filter =
2269 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2270 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
2271 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2272 trace_wrapper_->filter_);
2275 // Test that we can set the outgoing SSRC properly.
2276 // SSRC is set in SetupEngine by calling AddSendStream.
2277 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2278 EXPECT_TRUE(SetupEngine());
2279 int channel_num = voe_.GetLastChannel();
2280 unsigned int send_ssrc;
2281 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2282 EXPECT_NE(0U, send_ssrc);
2283 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2284 EXPECT_EQ(kSsrc1, send_ssrc);
2287 TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2288 // Setup. We need send codec to be set to get all stats.
2289 EXPECT_TRUE(SetupEngine());
2290 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2291 // use a different SSRC.
2292 EXPECT_TRUE(channel_->AddRecvStream(
2293 cricket::StreamParams::CreateLegacy(kSsrc2)));
2294 std::vector<cricket::AudioCodec> codecs;
2295 codecs.push_back(kPcmuCodec);
2296 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2297 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2299 cricket::VoiceMediaInfo info;
2300 EXPECT_EQ(true, channel_->GetStats(&info));
2301 EXPECT_EQ(1u, info.senders.size());
2302 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
2303 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2304 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2305 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2306 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2307 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2308 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2309 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2310 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2311 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2312 // TODO(sriniv): Add testing for more fields. These are not populated
2313 // in FakeWebrtcVoiceEngine yet.
2314 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2315 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2316 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2317 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2318 // EXPECT_EQ(cricket::kIntStatValue,
2319 // info.senders[0].echo_return_loss_enhancement);
2321 EXPECT_EQ(0u, info.receivers.size());
2322 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2323 EXPECT_EQ(true, channel_->GetStats(&info));
2324 EXPECT_EQ(1u, info.receivers.size());
2326 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2327 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2328 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2329 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2330 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
2331 // TODO(sriniv): Add testing for more receiver fields.
2334 // Test that we can set the outgoing SSRC properly with multiple streams.
2335 // SSRC is set in SetupEngine by calling AddSendStream.
2336 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2337 EXPECT_TRUE(SetupEngine());
2338 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2339 int channel_num1 = voe_.GetLastChannel();
2340 unsigned int send_ssrc;
2341 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2342 EXPECT_EQ(kSsrc1, send_ssrc);
2344 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2345 int channel_num2 = voe_.GetLastChannel();
2346 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2347 EXPECT_EQ(kSsrc1, send_ssrc);
2350 // Test that the local SSRC is the same on sending and receiving channels if the
2351 // receive channel is created before the send channel.
2352 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2353 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2354 channel_ = engine_.CreateChannel();
2355 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2357 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2358 int receive_channel_num = voe_.GetLastChannel();
2359 EXPECT_TRUE(channel_->AddSendStream(
2360 cricket::StreamParams::CreateLegacy(1234)));
2361 int send_channel_num = voe_.GetLastChannel();
2363 unsigned int ssrc = 0;
2364 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2365 EXPECT_EQ(1234U, ssrc);
2367 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2368 EXPECT_EQ(1234U, ssrc);
2371 // Test that we can properly receive packets.
2372 TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2373 EXPECT_TRUE(SetupEngine());
2374 int channel_num = voe_.GetLastChannel();
2375 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2376 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2377 sizeof(kPcmuFrame)));
2380 // Test that we can properly receive packets on multiple streams.
2381 TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2382 EXPECT_TRUE(SetupEngine());
2383 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2384 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2385 int channel_num1 = voe_.GetLastChannel();
2386 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2387 int channel_num2 = voe_.GetLastChannel();
2388 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2389 int channel_num3 = voe_.GetLastChannel();
2390 // Create packets with the right SSRCs.
2391 char packets[4][sizeof(kPcmuFrame)];
2392 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2393 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2394 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
2396 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2397 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2398 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2399 DeliverPacket(packets[0], sizeof(packets[0]));
2400 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2401 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2402 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2403 DeliverPacket(packets[1], sizeof(packets[1]));
2404 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2405 sizeof(packets[1])));
2406 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2407 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2408 DeliverPacket(packets[2], sizeof(packets[2]));
2409 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2410 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2411 sizeof(packets[2])));
2412 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2413 DeliverPacket(packets[3], sizeof(packets[3]));
2414 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2415 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2416 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2417 sizeof(packets[3])));
2418 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2419 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2420 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2423 // Test that we properly handle failures to add a stream.
2424 TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2425 EXPECT_TRUE(SetupEngine());
2426 voe_.set_fail_create_channel(true);
2427 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2428 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2430 // In 1:1 call, we should not try to create a new channel.
2431 cricket::AudioOptions options_no_conference_;
2432 options_no_conference_.conference_mode.Set(false);
2433 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2434 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2437 // Test that AddRecvStream doesn't create new channel for 1:1 call.
2438 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2439 EXPECT_TRUE(SetupEngine());
2440 int channel_num = voe_.GetLastChannel();
2441 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2442 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2445 // Test that after adding a recv stream, we do not decode more codecs than
2446 // those previously passed into SetRecvCodecs.
2447 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2448 EXPECT_TRUE(SetupEngine());
2449 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2450 std::vector<cricket::AudioCodec> codecs;
2451 codecs.push_back(kIsacCodec);
2452 codecs.push_back(kPcmuCodec);
2453 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2454 EXPECT_TRUE(channel_->AddRecvStream(
2455 cricket::StreamParams::CreateLegacy(kSsrc1)));
2456 int channel_num2 = voe_.GetLastChannel();
2457 webrtc::CodecInst gcodec;
2458 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2459 gcodec.plfreq = 32000;
2460 gcodec.channels = 2;
2461 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2464 // Test that we properly clean up any streams that were added, even if
2465 // not explicitly removed.
2466 TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2467 EXPECT_TRUE(SetupEngine());
2468 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2469 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2470 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2471 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2474 EXPECT_EQ(0, voe_.GetNumChannels());
2477 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2478 EXPECT_TRUE(SetupEngine());
2479 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2482 TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2483 EXPECT_TRUE(SetupEngine());
2484 // Stream 1 reuses default channel.
2485 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2486 // Manually delete default channel to simulate a failure.
2487 int default_channel = voe_.GetLastChannel();
2488 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2489 // Add recv stream 2 should fail because default channel is gone.
2490 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2491 int new_channel = voe_.GetLastChannel();
2492 EXPECT_NE(default_channel, new_channel);
2493 // The last created channel should have already been deleted.
2494 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2497 // Test the InsertDtmf on default send stream as caller.
2498 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2499 TestInsertDtmf(0, true);
2502 // Test the InsertDtmf on default send stream as callee
2503 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2504 TestInsertDtmf(0, false);
2507 // Test the InsertDtmf on specified send stream as caller.
2508 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2509 TestInsertDtmf(kSsrc1, true);
2512 // Test the InsertDtmf on specified send stream as callee.
2513 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2514 TestInsertDtmf(kSsrc1, false);
2517 // Test that we can play a ringback tone properly in a single-stream call.
2518 TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2519 EXPECT_TRUE(SetupEngine());
2520 int channel_num = voe_.GetLastChannel();
2521 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2522 // Check we fail if no ringback tone specified.
2523 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2524 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2525 // Check we can set and play a ringback tone.
2526 EXPECT_TRUE(channel_->SetRingbackTone(
2527 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2528 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2529 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2530 // Check we can stop the tone manually.
2531 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2532 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2533 // Check we stop the tone if a packet arrives.
2534 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2535 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2536 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2537 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2540 // Test that we can play a ringback tone properly in a multi-stream call.
2541 TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2542 EXPECT_TRUE(SetupEngine());
2543 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2544 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2545 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2546 int channel_num = voe_.GetLastChannel();
2547 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2548 // Check we fail if no ringback tone specified.
2549 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2550 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2551 // Check we can set and play a ringback tone on the correct ssrc.
2552 EXPECT_TRUE(channel_->SetRingbackTone(
2553 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2554 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2555 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2556 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2557 // Check we can stop the tone manually.
2558 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2559 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2560 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2561 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2562 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2563 // Send a packet with SSRC 1; the tone should not stop.
2564 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2565 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2566 // Send a packet with SSRC 2; the tone should stop.
2567 char packet[sizeof(kPcmuFrame)];
2568 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2569 rtc::SetBE32(packet + 8, 2);
2570 DeliverPacket(packet, sizeof(packet));
2571 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2574 // Tests creating soundclips, and make sure they come from the right engine.
2575 TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2576 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2577 EXPECT_FALSE(voe_sc_.IsInited());
2578 soundclip_ = engine_.CreateSoundclip();
2579 EXPECT_TRUE(voe_sc_.IsInited());
2580 ASSERT_TRUE(soundclip_ != NULL);
2581 EXPECT_EQ(0, voe_.GetNumChannels());
2582 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2583 int channel_num = voe_sc_.GetLastChannel();
2584 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2587 EXPECT_EQ(0, voe_sc_.GetNumChannels());
2588 // Make sure the soundclip engine is uninitialized on shutdown, now that
2589 // we've initialized it by creating a soundclip.
2590 engine_.Terminate();
2591 EXPECT_FALSE(voe_sc_.IsInited());
2594 // Tests playing out a fake sound.
2595 TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2596 static const char kZeroes[16000] = {};
2597 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2598 soundclip_ = engine_.CreateSoundclip();
2599 ASSERT_TRUE(soundclip_ != NULL);
2600 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2603 TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2604 rtc::scoped_ptr<ChannelErrorListener> listener;
2605 cricket::WebRtcVoiceMediaChannel* media_channel;
2606 unsigned int ssrc = 0;
2608 EXPECT_TRUE(SetupEngine());
2609 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2610 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2612 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2613 listener.reset(new ChannelErrorListener(channel_));
2615 // Test on WebRtc VoE channel.
2616 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2617 VE_SATURATION_WARNING);
2618 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2620 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2621 EXPECT_EQ(ssrc, listener->ssrc());
2624 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2625 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2627 EXPECT_EQ(0U, listener->ssrc());
2629 // Add another stream and test on that.
2631 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2634 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2635 VE_SATURATION_WARNING);
2636 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2638 EXPECT_EQ(ssrc, listener->ssrc());
2640 // Testing a non-existing channel.
2642 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2643 VE_SATURATION_WARNING);
2644 EXPECT_EQ(0, listener->error());
2647 TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2648 EXPECT_TRUE(SetupEngine());
2649 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2650 std::vector<cricket::AudioCodec> codecs;
2651 codecs.push_back(kPcmuCodec);
2652 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2653 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2654 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2655 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2656 EXPECT_TRUE(channel_->SetPlayout(true));
2657 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2658 EXPECT_TRUE(channel_->SetPlayout(false));
2659 EXPECT_FALSE(channel_->SetPlayout(true));
2662 // Test that the Registering/Unregistering with the
2663 // webrtcvoiceengine works as expected
2664 TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2665 EXPECT_TRUE(SetupEngine());
2666 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2667 EXPECT_TRUE(channel_->AddRecvStream(
2668 cricket::StreamParams::CreateLegacy(kSsrc2)));
2669 cricket::FakeMediaProcessor vp_1;
2670 cricket::FakeMediaProcessor vp_2;
2672 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2673 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2674 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2675 voe_.TriggerProcessPacket(cricket::MPD_RX);
2676 voe_.TriggerProcessPacket(cricket::MPD_TX);
2678 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2679 EXPECT_EQ(1, vp_1.voice_frame_count());
2680 EXPECT_EQ(1, vp_2.voice_frame_count());
2682 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2685 voe_.TriggerProcessPacket(cricket::MPD_RX);
2686 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2687 EXPECT_EQ(1, vp_2.voice_frame_count());
2688 EXPECT_EQ(2, vp_1.voice_frame_count());
2690 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2693 voe_.TriggerProcessPacket(cricket::MPD_RX);
2694 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2695 EXPECT_EQ(2, vp_1.voice_frame_count());
2697 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2698 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2699 voe_.TriggerProcessPacket(cricket::MPD_RX);
2700 voe_.TriggerProcessPacket(cricket::MPD_TX);
2701 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2702 EXPECT_EQ(3, vp_1.voice_frame_count());
2704 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2706 cricket::MPD_RX_AND_TX));
2707 voe_.TriggerProcessPacket(cricket::MPD_TX);
2708 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2709 EXPECT_EQ(3, vp_1.voice_frame_count());
2710 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2711 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2712 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2714 // Test that we can register a processor on the receive channel on SSRC 0.
2715 // This tests the 1:1 case when the receive SSRC is unknown.
2716 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2717 voe_.TriggerProcessPacket(cricket::MPD_RX);
2718 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2719 EXPECT_EQ(4, vp_1.voice_frame_count());
2720 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2724 // The following tests test that FindChannelNumFromSsrc is doing
2726 // pick an invalid ssrc and make sure we can't register
2727 EXPECT_FALSE(engine_.RegisterProcessor(99,
2730 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2731 EXPECT_TRUE(engine_.RegisterProcessor(1,
2734 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2737 EXPECT_FALSE(engine_.RegisterProcessor(1,
2740 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2743 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2744 EXPECT_TRUE(SetupEngine());
2747 webrtc::EcModes ec_mode;
2748 bool ec_metrics_enabled;
2749 webrtc::AecmModes aecm_mode;
2752 webrtc::AgcModes agc_mode;
2753 webrtc::AgcConfig agc_config;
2755 webrtc::NsModes ns_mode;
2756 bool highpass_filter_enabled;
2757 bool stereo_swapping_enabled;
2758 bool typing_detection_enabled;
2759 voe_.GetEcStatus(ec_enabled, ec_mode);
2760 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2761 voe_.GetAecmMode(aecm_mode, cng_enabled);
2762 voe_.GetAgcStatus(agc_enabled, agc_mode);
2763 voe_.GetAgcConfig(agc_config);
2764 voe_.GetNsStatus(ns_enabled, ns_mode);
2765 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2766 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2767 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2768 EXPECT_TRUE(ec_enabled);
2769 EXPECT_TRUE(ec_metrics_enabled);
2770 EXPECT_FALSE(cng_enabled);
2771 EXPECT_TRUE(agc_enabled);
2772 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2773 EXPECT_TRUE(ns_enabled);
2774 EXPECT_TRUE(highpass_filter_enabled);
2775 EXPECT_FALSE(stereo_swapping_enabled);
2776 EXPECT_TRUE(typing_detection_enabled);
2777 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2778 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2780 // Nothing set, so all ignored.
2781 cricket::AudioOptions options;
2782 ASSERT_TRUE(engine_.SetOptions(options));
2783 voe_.GetEcStatus(ec_enabled, ec_mode);
2784 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2785 voe_.GetAecmMode(aecm_mode, cng_enabled);
2786 voe_.GetAgcStatus(agc_enabled, agc_mode);
2787 voe_.GetAgcConfig(agc_config);
2788 voe_.GetNsStatus(ns_enabled, ns_mode);
2789 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2790 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2791 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2792 EXPECT_TRUE(ec_enabled);
2793 EXPECT_TRUE(ec_metrics_enabled);
2794 EXPECT_FALSE(cng_enabled);
2795 EXPECT_TRUE(agc_enabled);
2796 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2797 EXPECT_TRUE(ns_enabled);
2798 EXPECT_TRUE(highpass_filter_enabled);
2799 EXPECT_FALSE(stereo_swapping_enabled);
2800 EXPECT_TRUE(typing_detection_enabled);
2801 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2802 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2804 // Turn echo cancellation off
2805 options.echo_cancellation.Set(false);
2806 ASSERT_TRUE(engine_.SetOptions(options));
2807 voe_.GetEcStatus(ec_enabled, ec_mode);
2808 EXPECT_FALSE(ec_enabled);
2810 // Turn echo cancellation back on, with settings, and make sure
2811 // nothing else changed.
2812 options.echo_cancellation.Set(true);
2813 ASSERT_TRUE(engine_.SetOptions(options));
2814 voe_.GetEcStatus(ec_enabled, ec_mode);
2815 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2816 voe_.GetAecmMode(aecm_mode, cng_enabled);
2817 voe_.GetAgcStatus(agc_enabled, agc_mode);
2818 voe_.GetAgcConfig(agc_config);
2819 voe_.GetNsStatus(ns_enabled, ns_mode);
2820 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2821 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2822 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2823 EXPECT_TRUE(ec_enabled);
2824 EXPECT_TRUE(ec_metrics_enabled);
2825 EXPECT_TRUE(agc_enabled);
2826 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2827 EXPECT_TRUE(ns_enabled);
2828 EXPECT_TRUE(highpass_filter_enabled);
2829 EXPECT_FALSE(stereo_swapping_enabled);
2830 EXPECT_TRUE(typing_detection_enabled);
2831 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2832 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2835 options.auto_gain_control.Set(false);
2836 ASSERT_TRUE(engine_.SetOptions(options));
2837 voe_.GetAgcStatus(agc_enabled, agc_mode);
2838 EXPECT_FALSE(agc_enabled);
2841 options.auto_gain_control.Set(true);
2842 options.adjust_agc_delta.Clear();
2843 ASSERT_TRUE(engine_.SetOptions(options));
2844 voe_.GetAgcStatus(agc_enabled, agc_mode);
2845 EXPECT_TRUE(agc_enabled);
2846 voe_.GetAgcConfig(agc_config);
2847 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2849 // Turn off other options (and stereo swapping on).
2850 options.noise_suppression.Set(false);
2851 options.highpass_filter.Set(false);
2852 options.typing_detection.Set(false);
2853 options.stereo_swapping.Set(true);
2854 ASSERT_TRUE(engine_.SetOptions(options));
2855 voe_.GetNsStatus(ns_enabled, ns_mode);
2856 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2857 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2858 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2859 EXPECT_FALSE(ns_enabled);
2860 EXPECT_FALSE(highpass_filter_enabled);
2861 EXPECT_FALSE(typing_detection_enabled);
2862 EXPECT_TRUE(stereo_swapping_enabled);
2864 // Turn on "conference mode" to ensure it has no impact.
2865 options.conference_mode.Set(true);
2866 ASSERT_TRUE(engine_.SetOptions(options));
2867 voe_.GetEcStatus(ec_enabled, ec_mode);
2868 voe_.GetNsStatus(ns_enabled, ns_mode);
2869 EXPECT_TRUE(ec_enabled);
2870 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2871 EXPECT_FALSE(ns_enabled);
2872 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2875 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2876 EXPECT_TRUE(SetupEngine());
2879 webrtc::EcModes ec_mode;
2880 bool ec_metrics_enabled;
2882 webrtc::AgcModes agc_mode;
2884 webrtc::NsModes ns_mode;
2885 bool highpass_filter_enabled;
2886 bool stereo_swapping_enabled;
2887 bool typing_detection_enabled;
2889 voe_.GetEcStatus(ec_enabled, ec_mode);
2890 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2891 voe_.GetAgcStatus(agc_enabled, agc_mode);
2892 voe_.GetNsStatus(ns_enabled, ns_mode);
2893 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2894 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2895 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2896 EXPECT_TRUE(ec_enabled);
2897 EXPECT_TRUE(agc_enabled);
2898 EXPECT_TRUE(ns_enabled);
2899 EXPECT_TRUE(highpass_filter_enabled);
2900 EXPECT_TRUE(typing_detection_enabled);
2901 EXPECT_FALSE(stereo_swapping_enabled);
2904 TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2905 webrtc::AgcConfig set_config = {0};
2906 set_config.targetLeveldBOv = 3;
2907 set_config.digitalCompressionGaindB = 9;
2908 set_config.limiterEnable = true;
2909 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2910 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2912 webrtc::AgcConfig config = {0};
2913 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2914 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2915 EXPECT_EQ(set_config.digitalCompressionGaindB,
2916 config.digitalCompressionGaindB);
2917 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2920 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2921 EXPECT_TRUE(SetupEngine());
2922 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2923 engine_.CreateChannel());
2924 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2925 engine_.CreateChannel());
2927 // Have to add a stream to make SetSend work.
2928 cricket::StreamParams stream1;
2929 stream1.ssrcs.push_back(1);
2930 channel1->AddSendStream(stream1);
2931 cricket::StreamParams stream2;
2932 stream2.ssrcs.push_back(2);
2933 channel2->AddSendStream(stream2);
2935 // AEC and AGC and NS
2936 cricket::AudioOptions options_all;
2937 options_all.echo_cancellation.Set(true);
2938 options_all.auto_gain_control.Set(true);
2939 options_all.noise_suppression.Set(true);
2941 ASSERT_TRUE(channel1->SetOptions(options_all));
2942 cricket::AudioOptions expected_options = options_all;
2943 cricket::AudioOptions actual_options;
2944 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2945 EXPECT_EQ(expected_options, actual_options);
2946 ASSERT_TRUE(channel2->SetOptions(options_all));
2947 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2948 EXPECT_EQ(expected_options, actual_options);
2951 cricket::AudioOptions options_no_ns;
2952 options_no_ns.noise_suppression.Set(false);
2953 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2955 expected_options.echo_cancellation.Set(true);
2956 expected_options.auto_gain_control.Set(true);
2957 expected_options.noise_suppression.Set(false);
2958 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2959 EXPECT_EQ(expected_options, actual_options);
2962 cricket::AudioOptions options_no_agc;
2963 options_no_agc.auto_gain_control.Set(false);
2964 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2966 expected_options.echo_cancellation.Set(true);
2967 expected_options.auto_gain_control.Set(false);
2968 expected_options.noise_suppression.Set(true);
2969 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2970 EXPECT_EQ(expected_options, actual_options);
2972 ASSERT_TRUE(engine_.SetOptions(options_all));
2974 webrtc::EcModes ec_mode;
2976 webrtc::AgcModes agc_mode;
2978 webrtc::NsModes ns_mode;
2979 voe_.GetEcStatus(ec_enabled, ec_mode);
2980 voe_.GetAgcStatus(agc_enabled, agc_mode);
2981 voe_.GetNsStatus(ns_enabled, ns_mode);
2982 EXPECT_TRUE(ec_enabled);
2983 EXPECT_TRUE(agc_enabled);
2984 EXPECT_TRUE(ns_enabled);
2986 channel1->SetSend(cricket::SEND_MICROPHONE);
2987 voe_.GetEcStatus(ec_enabled, ec_mode);
2988 voe_.GetAgcStatus(agc_enabled, agc_mode);
2989 voe_.GetNsStatus(ns_enabled, ns_mode);
2990 EXPECT_TRUE(ec_enabled);
2991 EXPECT_TRUE(agc_enabled);
2992 EXPECT_FALSE(ns_enabled);
2994 channel1->SetSend(cricket::SEND_NOTHING);
2995 voe_.GetEcStatus(ec_enabled, ec_mode);
2996 voe_.GetAgcStatus(agc_enabled, agc_mode);
2997 voe_.GetNsStatus(ns_enabled, ns_mode);
2998 EXPECT_TRUE(ec_enabled);
2999 EXPECT_TRUE(agc_enabled);
3000 EXPECT_TRUE(ns_enabled);
3002 channel2->SetSend(cricket::SEND_MICROPHONE);
3003 voe_.GetEcStatus(ec_enabled, ec_mode);
3004 voe_.GetAgcStatus(agc_enabled, agc_mode);
3005 voe_.GetNsStatus(ns_enabled, ns_mode);
3006 EXPECT_TRUE(ec_enabled);
3007 EXPECT_FALSE(agc_enabled);
3008 EXPECT_TRUE(ns_enabled);
3010 channel2->SetSend(cricket::SEND_NOTHING);
3011 voe_.GetEcStatus(ec_enabled, ec_mode);
3012 voe_.GetAgcStatus(agc_enabled, agc_mode);
3013 voe_.GetNsStatus(ns_enabled, ns_mode);
3014 EXPECT_TRUE(ec_enabled);
3015 EXPECT_TRUE(agc_enabled);
3016 EXPECT_TRUE(ns_enabled);
3018 // Make sure settings take effect while we are sending.
3019 ASSERT_TRUE(engine_.SetOptions(options_all));
3020 cricket::AudioOptions options_no_agc_nor_ns;
3021 options_no_agc_nor_ns.auto_gain_control.Set(false);
3022 options_no_agc_nor_ns.noise_suppression.Set(false);
3023 channel2->SetSend(cricket::SEND_MICROPHONE);
3024 channel2->SetOptions(options_no_agc_nor_ns);
3026 expected_options.echo_cancellation.Set(true);
3027 expected_options.auto_gain_control.Set(false);
3028 expected_options.noise_suppression.Set(false);
3029 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3030 EXPECT_EQ(expected_options, actual_options);
3031 voe_.GetEcStatus(ec_enabled, ec_mode);
3032 voe_.GetAgcStatus(agc_enabled, agc_mode);
3033 voe_.GetNsStatus(ns_enabled, ns_mode);
3034 EXPECT_TRUE(ec_enabled);
3035 EXPECT_FALSE(agc_enabled);
3036 EXPECT_FALSE(ns_enabled);
3039 // This test verifies DSCP settings are properly applied on voice media channel.
3040 TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3041 EXPECT_TRUE(SetupEngine());
3042 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
3043 engine_.CreateChannel());
3044 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
3045 new cricket::FakeNetworkInterface);
3046 channel->SetInterface(network_interface.get());
3047 cricket::AudioOptions options;
3048 options.dscp.Set(true);
3049 EXPECT_TRUE(channel->SetOptions(options));
3050 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
3051 // Verify previous value is not modified if dscp option is not set.
3052 cricket::AudioOptions options1;
3053 EXPECT_TRUE(channel->SetOptions(options1));
3054 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
3055 options.dscp.Set(false);
3056 EXPECT_TRUE(channel->SetOptions(options));
3057 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
3060 TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3061 cricket::WebRtcVoiceEngine engine;
3062 cricket::AudioOptions options = engine.GetOptions();
3063 // The default options should have at least a few things set. We purposefully
3064 // don't check the option values here, though.
3065 EXPECT_TRUE(options.echo_cancellation.IsSet());
3066 EXPECT_TRUE(options.auto_gain_control.IsSet());
3067 EXPECT_TRUE(options.noise_suppression.IsSet());
3070 // Test that GetReceiveChannelNum returns the default channel for the first
3071 // recv stream in 1-1 calls.
3072 TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3073 EXPECT_TRUE(SetupEngine());
3074 cricket::WebRtcVoiceMediaChannel* media_channel =
3075 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3076 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3077 EXPECT_EQ(media_channel->voe_channel(),
3078 media_channel->GetReceiveChannelNum(0));
3079 cricket::StreamParams stream;
3080 stream.ssrcs.push_back(kSsrc2);
3081 EXPECT_TRUE(channel_->AddRecvStream(stream));
3082 EXPECT_EQ(media_channel->voe_channel(),
3083 media_channel->GetReceiveChannelNum(kSsrc2));
3086 // Test that GetReceiveChannelNum doesn't return the default channel for the
3087 // first recv stream in conference calls.
3088 TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3089 EXPECT_TRUE(SetupEngine());
3090 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3091 cricket::StreamParams stream;
3092 stream.ssrcs.push_back(kSsrc2);
3093 EXPECT_TRUE(channel_->AddRecvStream(stream));
3094 cricket::WebRtcVoiceMediaChannel* media_channel =
3095 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3096 EXPECT_LT(media_channel->voe_channel(),
3097 media_channel->GetReceiveChannelNum(kSsrc2));
3100 TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3101 EXPECT_TRUE(SetupEngine());
3103 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
3104 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
3105 EXPECT_DOUBLE_EQ(1, left);
3106 EXPECT_DOUBLE_EQ(2, right);
3108 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3109 cricket::StreamParams stream;
3110 stream.ssrcs.push_back(kSsrc2);
3111 EXPECT_TRUE(channel_->AddRecvStream(stream));
3113 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
3114 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
3115 EXPECT_DOUBLE_EQ(2, left);
3116 EXPECT_DOUBLE_EQ(1, right);
3119 // Tests for the actual WebRtc VoE library.
3121 // Tests that the library initializes and shuts down properly.
3122 TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3123 cricket::WebRtcVoiceEngine engine;
3124 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3125 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3126 EXPECT_TRUE(channel != NULL);
3130 // Reinit to catch regression where VoiceEngineObserver reference is lost
3131 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3135 // Tests that the logging from the library is cleartext.
3136 TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
3137 cricket::WebRtcVoiceEngine engine;
3138 rtc::scoped_ptr<rtc::MemoryStream> stream(
3139 new rtc::MemoryStream);
3141 bool cleartext = true;
3142 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3143 engine.SetLogging(rtc::LS_VERBOSE, "");
3144 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3145 EXPECT_TRUE(stream->GetSize(&size));
3146 EXPECT_GT(size, 0U);
3148 rtc::LogMessage::RemoveLogToStream(stream.get());
3149 const char* buf = stream->GetBuffer();
3150 for (size_t i = 0; i < size && cleartext; ++i) {
3151 int ch = static_cast<int>(buf[i]);
3152 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3154 cleartext = (isprint(ch) || isspace(ch));
3156 EXPECT_TRUE(cleartext);
3159 // Tests we do not see any references to a monitor thread being spun up
3160 // when initiating the engine.
3161 TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
3162 cricket::WebRtcVoiceEngine engine;
3163 rtc::scoped_ptr<rtc::MemoryStream> stream(
3164 new rtc::MemoryStream);
3165 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3166 engine.SetLogging(rtc::LS_VERBOSE, "");
3167 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3169 rtc::LogMessage::RemoveLogToStream(stream.get());
3172 EXPECT_TRUE(stream->GetSize(&size));
3173 EXPECT_GT(size, 0U);
3174 const std::string logs(stream->GetBuffer(), size);
3175 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
3178 // Tests that the library is configured with the codecs we want.
3179 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3180 cricket::WebRtcVoiceEngine engine;
3181 // Check codecs by name.
3182 EXPECT_TRUE(engine.FindCodec(
3183 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3184 EXPECT_TRUE(engine.FindCodec(
3185 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3186 EXPECT_TRUE(engine.FindCodec(
3187 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3188 // Check that name matching is case-insensitive.
3189 EXPECT_TRUE(engine.FindCodec(
3190 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3191 EXPECT_TRUE(engine.FindCodec(
3192 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3193 EXPECT_TRUE(engine.FindCodec(
3194 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3195 EXPECT_TRUE(engine.FindCodec(
3196 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3197 EXPECT_TRUE(engine.FindCodec(
3198 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
3199 EXPECT_TRUE(engine.FindCodec(
3200 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
3201 EXPECT_TRUE(engine.FindCodec(
3202 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3203 EXPECT_TRUE(engine.FindCodec(
3204 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3205 EXPECT_TRUE(engine.FindCodec(
3206 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3207 EXPECT_TRUE(engine.FindCodec(
3208 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3209 // Check codecs with an id by id.
3210 EXPECT_TRUE(engine.FindCodec(
3211 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3212 EXPECT_TRUE(engine.FindCodec(
3213 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3214 EXPECT_TRUE(engine.FindCodec(
3215 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
3216 EXPECT_TRUE(engine.FindCodec(
3217 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3218 // Check sample/bitrate matching.
3219 EXPECT_TRUE(engine.FindCodec(
3220 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3221 // Check that bad codecs fail.
3222 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3223 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3224 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3225 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3226 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
3227 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3228 for (std::vector<cricket::AudioCodec>::const_iterator it =
3229 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3230 if (it->name == "CN" && it->clockrate == 16000) {
3231 EXPECT_EQ(105, it->id);
3232 } else if (it->name == "CN" && it->clockrate == 32000) {
3233 EXPECT_EQ(106, it->id);
3234 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3235 EXPECT_EQ(103, it->id);
3236 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3237 EXPECT_EQ(104, it->id);
3238 } else if (it->name == "G722" && it->clockrate == 16000) {
3239 EXPECT_EQ(9, it->id);
3240 } else if (it->name == "telephone-event") {
3241 EXPECT_EQ(126, it->id);
3242 } else if (it->name == "red") {
3243 EXPECT_EQ(127, it->id);
3244 } else if (it->name == "opus") {
3245 EXPECT_EQ(111, it->id);
3246 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3247 EXPECT_EQ("10", it->params.find("minptime")->second);
3248 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3249 EXPECT_EQ("60", it->params.find("maxptime")->second);
3256 // Tests that VoE supports at least 32 channels
3257 TEST(WebRtcVoiceEngineTest, Has32Channels) {
3258 cricket::WebRtcVoiceEngine engine;
3259 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3261 cricket::VoiceMediaChannel* channels[32];
3262 int num_channels = 0;
3264 while (num_channels < ARRAY_SIZE(channels)) {
3265 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3269 channels[num_channels++] = channel;
3272 int expected = ARRAY_SIZE(channels);
3273 EXPECT_EQ(expected, num_channels);
3275 while (num_channels > 0) {
3276 delete channels[--num_channels];
3282 // Test that we set our preferred codecs properly.
3283 TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3284 cricket::WebRtcVoiceEngine engine;
3285 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3286 cricket::WebRtcVoiceMediaChannel channel(&engine);
3287 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3291 // Test our workarounds to WebRtc VoE' munging of the coinit count
3292 TEST(WebRtcVoiceEngineTest, CoInitialize) {
3293 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3295 // Initial refcount should be 0.
3296 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3298 // Engine should start even with COM already inited.
3299 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
3300 engine->Terminate();
3301 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
3302 engine->Terminate();
3304 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3305 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3306 // Decrement refcount to (hopefully) 0.
3311 // Ensure refcount is 0.
3312 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3317 TEST_F(WebRtcVoiceEngineTestFake, ChangeCombinedAudioVideoBweOption) {
3318 // Test that changing the combined_audio_video_bwe option results in the
3319 // expected state changes in VoiceEngine.
3320 cricket::ViEWrapper vie;
3321 const int kVieCh = 667;
3323 EXPECT_TRUE(SetupEngine());
3324 cricket::WebRtcVoiceMediaChannel* media_channel =
3325 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3326 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3328 EXPECT_TRUE(media_channel->AddRecvStream(
3329 cricket::StreamParams::CreateLegacy(2)));
3330 int recv_ch = voe_.GetLastChannel();
3332 // Combined BWE should not be set up yet.
3333 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3334 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3336 // Enable combined BWE option - now it should be set up.
3337 cricket::AudioOptions options;
3338 options.combined_audio_video_bwe.Set(true);
3339 EXPECT_TRUE(media_channel->SetOptions(options));
3340 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3341 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3343 // Disable combined BWE option - should be disabled again.
3344 options.combined_audio_video_bwe.Set(false);
3345 EXPECT_TRUE(media_channel->SetOptions(options));
3346 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3347 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3349 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3352 TEST_F(WebRtcVoiceEngineTestFake, SetupSharedBandwidthEstimation) {
3353 // Test that calling SetupSharedBandwidthEstimation() on the voice media
3354 // channel results in the expected state changes in VoiceEngine.
3355 cricket::ViEWrapper vie1;
3356 cricket::ViEWrapper vie2;
3357 const int kVieCh1 = 667;
3358 const int kVieCh2 = 70;
3360 EXPECT_TRUE(SetupEngine());
3361 cricket::WebRtcVoiceMediaChannel* media_channel =
3362 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3363 cricket::AudioOptions options;
3364 options.combined_audio_video_bwe.Set(true);
3365 EXPECT_TRUE(media_channel->SetOptions(options));
3366 EXPECT_TRUE(media_channel->AddRecvStream(
3367 cricket::StreamParams::CreateLegacy(2)));
3368 int recv_ch = voe_.GetLastChannel();
3370 // Combined BWE should not be set up yet.
3371 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3372 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3374 // Register - should be enabled.
3375 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie1.engine(),
3377 EXPECT_EQ(vie1.network(), voe_.GetViENetwork(recv_ch));
3378 EXPECT_EQ(kVieCh1, voe_.GetVideoChannel(recv_ch));
3380 // Re-register - should still be enabled.
3381 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie2.engine(),
3383 EXPECT_EQ(vie2.network(), voe_.GetViENetwork(recv_ch));
3384 EXPECT_EQ(kVieCh2, voe_.GetVideoChannel(recv_ch));
3386 // Unregister - should be disabled again.
3387 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3388 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3389 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3392 TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
3393 // Test that adding receive streams after enabling combined bandwidth
3394 // estimation will correctly configure each channel.
3395 cricket::ViEWrapper vie;
3396 const int kVieCh = 667;
3398 EXPECT_TRUE(SetupEngine());
3399 cricket::WebRtcVoiceMediaChannel* media_channel =
3400 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3401 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3403 cricket::AudioOptions options;
3404 options.combined_audio_video_bwe.Set(true);
3405 EXPECT_TRUE(media_channel->SetOptions(options));
3407 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3408 int voe_channels[ARRAY_SIZE(kSsrcs)] = {0};
3409 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3410 EXPECT_TRUE(media_channel->AddRecvStream(
3411 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3412 int recv_ch = media_channel->GetReceiveChannelNum(kSsrcs[i]);
3413 EXPECT_NE(-1, recv_ch);
3414 voe_channels[i] = recv_ch;
3415 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3416 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3419 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3421 for (unsigned int i = 0; i < ARRAY_SIZE(voe_channels); ++i) {
3422 EXPECT_EQ(NULL, voe_.GetViENetwork(voe_channels[i]));
3423 EXPECT_EQ(-1, voe_.GetVideoChannel(voe_channels[i]));