1 /* 2 * libjingle 3 * Copyright 2008 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifdef WIN32 29 #include "webrtc/base/win32.h" 30 #include <objbase.h> 31 #endif 32 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" 45 46 // Tests for the WebRtcVoiceEngine/VoiceChannel code. 47 48 using cricket::kRtpAudioLevelHeaderExtension; 49 using cricket::kRtpAbsoluteSenderTimeHeaderExtension; 50 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, 63 }; 64 const char kRingbackTone[] = "RIFF____WAVE____ABCD1234"; 65 static uint32 kSsrc1 = 0x99; 66 static uint32 kSsrc2 = 0x98; 67 68 class FakeVoEWrapper : public cricket::VoEWrapper { 69 public: 70 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine) 71 : cricket::VoEWrapper(engine, // processing 72 engine, // base 73 engine, // codec 74 engine, // dtmf 75 engine, // file 76 engine, // hw 77 engine, // media 78 engine, // neteq 79 engine, // network 80 engine, // rtp 81 engine, // sync 82 engine) { // volume 83 } 84 }; 85 86 class FakeVoETraceWrapper : public cricket::VoETraceWrapper { 87 public: 88 virtual int SetTraceFilter(const unsigned int filter) { 89 filter_ = filter; 90 return 0; 91 } 92 virtual int SetTraceFile(const char* fileNameUTF8) { 93 return 0; 94 } 95 virtual int SetTraceCallback(webrtc::TraceCallback* callback) { 96 return 0; 97 } 98 unsigned int filter_; 99 }; 100 101 class WebRtcVoiceEngineTestFake : public testing::Test { 102 public: 103 class ChannelErrorListener : public sigslot::has_slots<> { 104 public: 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); 110 } 111 void OnVoiceChannelError(uint32 ssrc, 112 cricket::VoiceMediaChannel::Error error) { 113 ssrc_ = ssrc; 114 error_ = error; 115 } 116 void Reset() { 117 ssrc_ = 0; 118 error_ = cricket::VoiceMediaChannel::ERROR_NONE; 119 } 120 uint32 ssrc() const { 121 return ssrc_; 122 } 123 cricket::VoiceMediaChannel::Error error() const { 124 return error_; 125 } 126 127 private: 128 uint32 ssrc_; 129 cricket::VoiceMediaChannel::Error error_; 130 }; 131 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_), 138 trace_wrapper_), 139 channel_(NULL), soundclip_(NULL) { 140 options_conference_.conference_mode.Set(true); 141 options_adjust_agc_.adjust_agc_delta.Set(-10); 142 } 143 bool SetupEngineWithoutStream() { 144 if (!engine_.Init(rtc::Thread::Current())) { 145 return false; 146 } 147 channel_ = engine_.CreateChannel(); 148 return (channel_ != NULL); 149 } 150 bool SetupEngine() { 151 if (!SetupEngineWithoutStream()) { 152 return false; 153 } 154 return channel_->AddSendStream( 155 cricket::StreamParams::CreateLegacy(kSsrc1)); 156 } 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)); 165 166 // Verify the default channel still exists. 167 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc)); 168 } 169 void DeliverPacket(const void* data, int len) { 170 rtc::Buffer packet(data, len); 171 channel_->OnPacketReceived(&packet, rtc::PacketTime()); 172 } 173 virtual void TearDown() { 174 delete soundclip_; 175 delete channel_; 176 engine_.Terminate(); 177 } 178 179 void TestInsertDtmf(uint32 ssrc, bool caller) { 180 EXPECT_TRUE(engine_.Init(rtc::Thread::Current())); 181 channel_ = engine_.CreateChannel(); 182 EXPECT_TRUE(channel_ != NULL); 183 if (caller) { 184 // if this is a caller, local description will be applied and add the 185 // send stream. 186 EXPECT_TRUE(channel_->AddSendStream( 187 cricket::StreamParams::CreateLegacy(kSsrc1))); 188 } 189 int channel_id = voe_.GetLastChannel(); 190 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()); 201 202 if (!caller) { 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))); 207 } 208 209 // Check we fail if the ssrc is invalid. 210 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND)); 211 212 // Test 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)); 216 217 // Test play 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)); 221 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)); 229 } 230 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, 237 int max_bitrate, 238 bool expected_result, 239 int expected_bitrate) { 240 int channel_num = voe_.GetLastChannel(); 241 std::vector<cricket::AudioCodec> codecs; 242 243 codecs.push_back(codec); 244 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 245 246 bool result = channel_->SetMaxSendBandwidth(max_bitrate); 247 EXPECT_EQ(expected_result, result); 248 249 webrtc::CodecInst temp_codec; 250 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec)); 251 252 EXPECT_EQ(expected_bitrate, temp_codec.rate); 253 } 254 255 void TestSetSendRtpHeaderExtensions(const std::string& ext) { 256 EXPECT_TRUE(SetupEngineWithoutStream()); 257 int channel_num = voe_.GetLastChannel(); 258 259 // Ensure extensions are off by default. 260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext)); 261 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)); 268 269 // Ensure extensions stay off with an empty list of headers. 270 extensions.clear(); 271 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 272 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext)); 273 274 // Ensure extension is set properly. 275 const int id = 1; 276 extensions.push_back(cricket::RtpHeaderExtension(ext, id)); 277 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 278 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext)); 279 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)); 289 290 // Ensure all extensions go back off with an empty list. 291 extensions.clear(); 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)); 295 } 296 297 void TestSetRecvRtpHeaderExtensions(const std::string& ext) { 298 EXPECT_TRUE(SetupEngineWithoutStream()); 299 int channel_num = voe_.GetLastChannel(); 300 301 // Ensure extensions are off by default. 302 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext)); 303 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)); 310 311 // Ensure extensions stay off with an empty list of headers. 312 extensions.clear(); 313 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 314 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext)); 315 316 // Ensure extension is set properly. 317 const int id = 2; 318 extensions.push_back(cricket::RtpHeaderExtension(ext, id)); 319 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 320 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext)); 321 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)); 331 332 // Ensure all extensions go back off with an empty list. 333 extensions.clear(); 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)); 337 } 338 339 protected: 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_; 346 347 cricket::AudioOptions options_conference_; 348 cricket::AudioOptions options_adjust_agc_; 349 }; 350 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()); 359 engine_.Terminate(); 360 EXPECT_FALSE(voe_.IsInited()); 361 EXPECT_FALSE(voe_sc_.IsInited()); 362 } 363 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); 369 } 370 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); 377 } 378 379 // Tests that the list of supported codecs is created properly and ordered 380 // correctly 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; 392 } 393 } 394 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. 407 codec = kIsacCodec; 408 codec.id = 127; 409 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst)); 410 EXPECT_EQ(codec.id, codec_inst.pltype); 411 // Find PCMU with a 0 clockrate. 412 codec = kPcmuCodec; 413 codec.clockrate = 0; 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. 418 codec = kPcmuCodec; 419 codec.bitrate = 0; 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. 424 codec = kIsacCodec; 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); 429 } 430 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 440 codecs[2].id = 126; 441 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 442 webrtc::CodecInst gcodec; 443 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC"); 444 gcodec.plfreq = 16000; 445 gcodec.channels = 1; 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), 450 "telephone-event"); 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); 455 } 456 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)); 464 } 465 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)); 474 } 475 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); 494 opus.pltype = 0; 495 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus)); 496 EXPECT_EQ(111, opus.pltype); 497 } 498 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); 518 opus.pltype = 0; 519 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus)); 520 EXPECT_EQ(111, opus.pltype); 521 } 522 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); 541 opus.pltype = 0; 542 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus)); 543 EXPECT_EQ(111, opus.pltype); 544 } 545 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 555 codecs[2].id = 126; 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; 563 gcodec.channels = 1; 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), 568 "telephone-event"); 569 gcodec.plfreq = 8000; 570 gcodec.channels = 1; 571 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); 572 EXPECT_EQ(126, gcodec.pltype); 573 EXPECT_STREQ("telephone-event", gcodec.plname); 574 } 575 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 582 583 EXPECT_TRUE(channel_->AddRecvStream( 584 cricket::StreamParams::CreateLegacy(kSsrc1))); 585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 586 587 int channel_num2 = voe_.GetLastChannel(); 588 webrtc::CodecInst gcodec; 589 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC"); 590 gcodec.plfreq = 16000; 591 gcodec.channels = 1; 592 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); 593 EXPECT_EQ(106, gcodec.pltype); 594 EXPECT_STREQ("ISAC", gcodec.plname); 595 } 596 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)); 607 608 // Changing the payload type of a codec should fail. 609 codecs[0].id = 127; 610 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); 611 EXPECT_TRUE(voe_.GetPlayout(channel_num)); 612 } 613 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)); 623 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); 630 } 631 632 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) { 633 EXPECT_TRUE(SetupEngine()); 634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 635 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 638 // bitrate is <= 0. 639 640 // ISAC, default bitrate == 32000. 641 TestSendBandwidth(kIsacCodec, 0, true, 32000); 642 643 // PCMU, default bitrate == 64000. 644 TestSendBandwidth(kPcmuCodec, -1, true, 64000); 645 646 // CELT, default bitrate == 64000. 647 TestSendBandwidth(kCeltCodec, 0, true, 64000); 648 649 // opus, default bitrate == 64000. 650 TestSendBandwidth(kOpusCodec, -1, true, 64000); 651 } 652 653 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) { 654 EXPECT_TRUE(SetupEngine()); 655 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 656 657 // Test that the bitrate of a multi-rate codec is always the maximum. 658 659 // ISAC, default bitrate == 32000. 660 TestSendBandwidth(kIsacCodec, 128000, true, 128000); 661 TestSendBandwidth(kIsacCodec, 16000, true, 16000); 662 663 // CELT, default bitrate == 64000. 664 TestSendBandwidth(kCeltCodec, 96000, true, 96000); 665 TestSendBandwidth(kCeltCodec, 32000, true, 32000); 666 667 // opus, default bitrate == 64000. 668 TestSendBandwidth(kOpusCodec, 96000, true, 96000); 669 TestSendBandwidth(kOpusCodec, 48000, true, 48000); 670 } 671 672 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) { 673 EXPECT_TRUE(SetupEngine()); 674 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 675 676 // Test that we can only set a maximum bitrate for a fixed-rate codec 677 // if it's bigger than the fixed rate. 678 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); 687 } 688 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())); 694 695 int desired_bitrate = 128000; 696 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate)); 697 698 EXPECT_TRUE(channel_->AddSendStream( 699 cricket::StreamParams::CreateLegacy(kSsrc1))); 700 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); 705 } 706 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())); 713 714 webrtc::CodecInst codec; 715 int channel_num = voe_.GetLastChannel(); 716 std::vector<cricket::AudioCodec> codecs; 717 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); 729 } 730 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); 739 codecs[0].id = 96; 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)); 753 } 754 755 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried 756 // to apply. 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); 763 codecs[0].id = 96; 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()); 771 } 772 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)); 781 } 782 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)); 791 } 792 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)); 802 } 803 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)); 812 } 813 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)); 823 } 824 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)); 834 } 835 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); 850 } 851 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); 867 } 868 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; 878 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); 887 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); 894 } 895 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); 911 } 912 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; 922 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); 931 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); 938 } 939 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); 956 } 957 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); 973 } 974 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); 989 } 990 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); 1006 } 1007 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; 1018 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); 1024 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); 1030 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); 1035 } 1036 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)); 1048 } 1049 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); 1055 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)); 1064 1065 EXPECT_TRUE(channel_->AddSendStream( 1066 cricket::StreamParams::CreateLegacy(kSsrc1))); 1067 EXPECT_TRUE(voe_.GetNACK(channel_num)); 1068 } 1069 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)); 1086 } 1087 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)); 1098 1099 codecs.clear(); 1100 codecs.push_back(kOpusCodec); 1101 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1102 EXPECT_FALSE(voe_.GetNACK(channel_num)); 1103 } 1104 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)); 1119 1120 codecs.clear(); 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)); 1125 } 1126 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)); 1139 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)); 1146 } 1147 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)); 1157 } 1158 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); 1174 } 1175 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); 1191 } 1192 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); 1209 } 1210 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)); 1219 } 1220 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)); 1230 } 1231 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)); 1243 } 1244 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); 1262 } 1263 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); 1281 } 1282 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); 1300 } 1301 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); 1319 } 1320 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); 1338 } 1339 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)); 1349 } 1350 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)); 1360 } 1361 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)); 1372 1373 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000); 1374 1375 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1376 EXPECT_EQ(cricket::kOpusBandwidthNb, 1377 voe_.GetMaxEncodingBandwidth(channel_num)); 1378 1379 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2)); 1380 channel_num = voe_.GetLastChannel(); 1381 EXPECT_EQ(cricket::kOpusBandwidthNb, 1382 voe_.GetMaxEncodingBandwidth(channel_num)); 1383 } 1384 #endif // USE_WEBRTC_DEV_BRANCH 1385 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); 1393 codecs[0].id = 96; 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); 1412 } 1413 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); 1425 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); 1434 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); 1439 } 1440 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); 1453 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); 1460 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); 1467 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); 1474 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); 1481 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); 1489 } 1490 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)); 1496 } 1497 1498 // Test that we can set send codecs even with telephone-event codec as the first 1499 // one on the list. 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 1508 codecs[1].id = 96; 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)); 1515 } 1516 1517 // Test that we can set send codecs even with CN codec as the first 1518 // one on the list. 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 1527 codecs[1].id = 96; 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)); 1534 } 1535 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); 1548 codecs[0].id = 96; 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)); 1561 } 1562 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); 1568 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); 1578 codecs[0].id = 96; 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))); 1584 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)); 1594 } 1595 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); 1605 codecs[1].id = 97; 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)); 1631 } 1632 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"; 1645 codecs[0].id = 96; 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)); 1658 } 1659 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); 1668 codecs[0].id = 127; 1669 codecs[0].params[""] = "96/96"; 1670 codecs[1].id = 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)); 1678 } 1679 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); 1685 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); 1691 codecs[0].id = 127; 1692 codecs[0].params[""] = "96/96"; 1693 codecs[1].id = 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)); 1703 } 1704 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); 1713 codecs[0].id = 127; 1714 codecs[1].id = 96; 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)); 1722 } 1723 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); 1732 codecs[0].id = 127; 1733 codecs[0].params["ABC"] = "96/96"; 1734 codecs[1].id = 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)); 1741 } 1742 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); 1751 codecs[0].id = 127; 1752 codecs[0].params[""] = "96/0"; 1753 codecs[1].id = 96; 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)); 1760 } 1761 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); 1770 codecs[0].id = 127; 1771 codecs[0].params[""] = "96/96/96"; 1772 codecs[1].id = 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)); 1779 } 1780 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); 1789 codecs[0].id = 127; 1790 codecs[0].params[""] = "ABC/ABC"; 1791 codecs[1].id = 96; 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)); 1798 } 1799 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); 1808 codecs[0].id = 127; 1809 codecs[0].params[""] = "97/97"; 1810 codecs[1].id = 96; 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)); 1817 } 1818 1819 // Test support for audio level header extension. 1820 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) { 1821 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension); 1822 } 1823 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) { 1824 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension); 1825 } 1826 1827 // Test support for absolute send time header extension. 1828 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) { 1829 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension); 1830 } 1831 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) { 1832 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension); 1833 } 1834 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)); 1850 } 1851 1852 // Test that we can add and remove send streams. 1853 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) { 1854 SetupForMultiSendStream(); 1855 1856 static const uint32 kSsrcs4[] = {1, 2, 3, 4}; 1857 1858 // Set the global state for sending. 1859 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE)); 1860 1861 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) { 1862 EXPECT_TRUE(channel_->AddSendStream( 1863 cricket::StreamParams::CreateLegacy(kSsrcs4[i]))); 1864 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)); 1868 } 1869 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])); 1877 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])); 1884 } 1885 } 1886 1887 // Test SetSendCodecs correctly configure the codecs in all send streams. 1888 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) { 1889 SetupForMultiSendStream(); 1890 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]))); 1896 } 1897 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); 1902 codecs[1].id = 97; 1903 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1904 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)); 1913 } 1914 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)); 1923 } 1924 } 1925 1926 // Test we can SetSend on all send streams correctly. 1927 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) { 1928 SetupForMultiSendStream(); 1929 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)); 1937 } 1938 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)); 1945 } 1946 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)); 1953 } 1954 } 1955 1956 // Test we can set the correct statistics on all send streams. 1957 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) { 1958 SetupForMultiSendStream(); 1959 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]))); 1965 } 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)); 1975 1976 cricket::VoiceMediaInfo info; 1977 EXPECT_EQ(true, channel_->GetStats(&info)); 1978 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size()); 1979 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); 1992 } 1993 1994 EXPECT_EQ(0u, info.receivers.size()); 1995 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); 1996 EXPECT_EQ(true, channel_->GetStats(&info)); 1997 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); 2004 } 2005 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(); 2011 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)); 2016 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)); 2026 2027 // Make sure only the new channel is played out. 2028 EXPECT_FALSE(voe_.GetPlayout(channel_num1)); 2029 EXPECT_TRUE(voe_.GetPlayout(channel_num2)); 2030 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)); 2038 2039 // Stop sending. 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)); 2044 2045 // Stop playout. 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)); 2050 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)); 2056 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)); 2061 2062 EXPECT_TRUE(voe_.GetPlayout(channel_num1)); 2063 } 2064 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)); 2072 2073 cricket::Device default_dev(cricket::kFakeDefaultDeviceName, 2074 cricket::kFakeDefaultDeviceId); 2075 cricket::Device dev(cricket::kFakeDeviceName, 2076 cricket::kFakeDeviceId); 2077 2078 // Test SetDevices() while not sending or playing. 2079 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev)); 2080 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)); 2088 2089 EXPECT_TRUE(engine_.SetDevices(&dev, &dev)); 2090 2091 EXPECT_TRUE(voe_.GetRecordingMicrophone()); 2092 EXPECT_TRUE(voe_.GetSend(channel_num)); 2093 EXPECT_TRUE(voe_.GetPlayout(channel_num)); 2094 2095 // Test that failure to open newly selected devices does not prevent opening 2096 // ones after that. 2097 voe_.set_fail_start_recording_microphone(true); 2098 voe_.set_playout_fail_channel(channel_num); 2099 voe_.set_send_fail_channel(channel_num); 2100 2101 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev)); 2102 2103 EXPECT_FALSE(voe_.GetRecordingMicrophone()); 2104 EXPECT_FALSE(voe_.GetSend(channel_num)); 2105 EXPECT_FALSE(voe_.GetPlayout(channel_num)); 2106 2107 voe_.set_fail_start_recording_microphone(false); 2108 voe_.set_playout_fail_channel(-1); 2109 voe_.set_send_fail_channel(-1); 2110 2111 EXPECT_TRUE(engine_.SetDevices(&dev, &dev)); 2112 2113 EXPECT_TRUE(voe_.GetRecordingMicrophone()); 2114 EXPECT_TRUE(voe_.GetSend(channel_num)); 2115 EXPECT_TRUE(voe_.GetPlayout(channel_num)); 2116 } 2117 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)); 2126 2127 cricket::Device default_dev(cricket::kFakeDefaultDeviceName, 2128 cricket::kFakeDefaultDeviceId); 2129 cricket::Device dev(cricket::kFakeDeviceName, 2130 cricket::kFakeDeviceId); 2131 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); 2137 2138 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev)); 2139 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)); 2146 2147 voe_.set_fail_start_recording_microphone(false); 2148 voe_.set_playout_fail_channel(-1); 2149 voe_.set_send_fail_channel(-1); 2150 2151 EXPECT_TRUE(engine_.SetDevices(&dev, &dev)); 2152 2153 EXPECT_TRUE(voe_.GetRecordingMicrophone()); 2154 EXPECT_TRUE(voe_.GetSend(channel_num)); 2155 EXPECT_TRUE(voe_.GetPlayout(channel_num)); 2156 } 2157 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)); 2169 } 2170 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)); 2195 } 2196 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); 2202 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)); 2209 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); 2214 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)); 2219 2220 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config)); 2221 EXPECT_EQ(13, agc_config.targetLeveldBOv); 2222 } 2223 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)); 2233 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); 2240 } 2241 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)); 2248 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); 2254 } 2255 2256 TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) { 2257 EXPECT_TRUE(SetupEngine()); 2258 engine_.SetLogging(rtc::LS_INFO, ""); 2259 EXPECT_EQ( 2260 // Info: 2261 webrtc::kTraceStateInfo | webrtc::kTraceInfo | 2262 // Warning: 2263 webrtc::kTraceTerseInfo | webrtc::kTraceWarning | 2264 // Error: 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_); 2273 } 2274 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); 2285 } 2286 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)); 2298 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); 2320 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()); 2325 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. 2332 } 2333 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); 2343 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); 2348 } 2349 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_)); 2356 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(); 2362 2363 unsigned int ssrc = 0; 2364 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc)); 2365 EXPECT_EQ(1234U, ssrc); 2366 ssrc = 0; 2367 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc)); 2368 EXPECT_EQ(1234U, ssrc); 2369 } 2370 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))); 2378 } 2379 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)); 2395 } 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)); 2421 } 2422 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))); 2429 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))); 2435 } 2436 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()); 2443 } 2444 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)); 2462 } 2463 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 2472 delete channel_; 2473 channel_ = NULL; 2474 EXPECT_EQ(0, voe_.GetNumChannels()); 2475 } 2476 2477 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) { 2478 EXPECT_TRUE(SetupEngine()); 2479 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0))); 2480 } 2481 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)); 2495 } 2496 2497 // Test the InsertDtmf on default send stream as caller. 2498 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) { 2499 TestInsertDtmf(0, true); 2500 } 2501 2502 // Test the InsertDtmf on default send stream as callee 2503 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) { 2504 TestInsertDtmf(0, false); 2505 } 2506 2507 // Test the InsertDtmf on specified send stream as caller. 2508 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) { 2509 TestInsertDtmf(kSsrc1, true); 2510 } 2511 2512 // Test the InsertDtmf on specified send stream as callee. 2513 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) { 2514 TestInsertDtmf(kSsrc1, false); 2515 } 2516 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)); 2538 } 2539 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)); 2572 } 2573 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)); 2585 delete soundclip_; 2586 soundclip_ = NULL; 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()); 2592 } 2593 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)); 2601 } 2602 2603 TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) { 2604 rtc::scoped_ptr<ChannelErrorListener> listener; 2605 cricket::WebRtcVoiceMediaChannel* media_channel; 2606 unsigned int ssrc = 0; 2607 2608 EXPECT_TRUE(SetupEngine()); 2609 EXPECT_TRUE(channel_->SetOptions(options_conference_)); 2610 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE)); 2611 2612 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_); 2613 listener.reset(new ChannelErrorListener(channel_)); 2614 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, 2619 listener->error()); 2620 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc)); 2621 EXPECT_EQ(ssrc, listener->ssrc()); 2622 2623 listener->Reset(); 2624 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING); 2625 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED, 2626 listener->error()); 2627 EXPECT_EQ(0U, listener->ssrc()); 2628 2629 // Add another stream and test on that. 2630 ++ssrc; 2631 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy( 2632 ssrc))); 2633 listener->Reset(); 2634 voe_.TriggerCallbackOnError(voe_.GetLastChannel(), 2635 VE_SATURATION_WARNING); 2636 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION, 2637 listener->error()); 2638 EXPECT_EQ(ssrc, listener->ssrc()); 2639 2640 // Testing a non-existing channel. 2641 listener->Reset(); 2642 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2, 2643 VE_SATURATION_WARNING); 2644 EXPECT_EQ(0, listener->error()); 2645 } 2646 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)); 2660 } 2661 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; 2671 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); 2677 2678 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered()); 2679 EXPECT_EQ(1, vp_1.voice_frame_count()); 2680 EXPECT_EQ(1, vp_2.voice_frame_count()); 2681 2682 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2, 2683 &vp_2, 2684 cricket::MPD_RX)); 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()); 2689 2690 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2, 2691 &vp_1, 2692 cricket::MPD_RX)); 2693 voe_.TriggerProcessPacket(cricket::MPD_RX); 2694 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered()); 2695 EXPECT_EQ(2, vp_1.voice_frame_count()); 2696 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()); 2703 2704 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1, 2705 &vp_1, 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()); 2713 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, 2721 &vp_1, 2722 cricket::MPD_RX)); 2723 2724 // The following tests test that FindChannelNumFromSsrc is doing 2725 // what we expect. 2726 // pick an invalid ssrc and make sure we can't register 2727 EXPECT_FALSE(engine_.RegisterProcessor(99, 2728 &vp_1, 2729 cricket::MPD_RX)); 2730 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 2731 EXPECT_TRUE(engine_.RegisterProcessor(1, 2732 &vp_1, 2733 cricket::MPD_RX)); 2734 EXPECT_TRUE(engine_.UnregisterProcessor(1, 2735 &vp_1, 2736 cricket::MPD_RX)); 2737 EXPECT_FALSE(engine_.RegisterProcessor(1, 2738 &vp_1, 2739 cricket::MPD_TX)); 2740 EXPECT_TRUE(channel_->RemoveRecvStream(1)); 2741 } 2742 2743 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) { 2744 EXPECT_TRUE(SetupEngine()); 2745 2746 bool ec_enabled; 2747 webrtc::EcModes ec_mode; 2748 bool ec_metrics_enabled; 2749 webrtc::AecmModes aecm_mode; 2750 bool cng_enabled; 2751 bool agc_enabled; 2752 webrtc::AgcModes agc_mode; 2753 webrtc::AgcConfig agc_config; 2754 bool ns_enabled; 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); 2779 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); 2803 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); 2809 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); 2833 2834 // Turn off AGC 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); 2839 2840 // Turn AGC back on 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); 2848 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); 2863 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); 2873 } 2874 2875 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) { 2876 EXPECT_TRUE(SetupEngine()); 2877 2878 bool ec_enabled; 2879 webrtc::EcModes ec_mode; 2880 bool ec_metrics_enabled; 2881 bool agc_enabled; 2882 webrtc::AgcModes agc_mode; 2883 bool ns_enabled; 2884 webrtc::NsModes ns_mode; 2885 bool highpass_filter_enabled; 2886 bool stereo_swapping_enabled; 2887 bool typing_detection_enabled; 2888 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); 2902 } 2903 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())); 2911 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); 2918 } 2919 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()); 2926 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); 2934 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); 2940 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); 2949 2950 // unset NS 2951 cricket::AudioOptions options_no_ns; 2952 options_no_ns.noise_suppression.Set(false); 2953 ASSERT_TRUE(channel1->SetOptions(options_no_ns)); 2954 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); 2960 2961 // unset AGC 2962 cricket::AudioOptions options_no_agc; 2963 options_no_agc.auto_gain_control.Set(false); 2964 ASSERT_TRUE(channel2->SetOptions(options_no_agc)); 2965 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); 2971 2972 ASSERT_TRUE(engine_.SetOptions(options_all)); 2973 bool ec_enabled; 2974 webrtc::EcModes ec_mode; 2975 bool agc_enabled; 2976 webrtc::AgcModes agc_mode; 2977 bool ns_enabled; 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); 2985 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); 2993 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); 3001 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); 3009 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); 3017 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); 3025 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); 3037 } 3038 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()); 3058 } 3059 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()); 3068 } 3069 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)); 3084 } 3085 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)); 3098 } 3099 3100 TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) { 3101 EXPECT_TRUE(SetupEngine()); 3102 double left, right; 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); 3107 3108 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2)); 3109 cricket::StreamParams stream; 3110 stream.ssrcs.push_back(kSsrc2); 3111 EXPECT_TRUE(channel_->AddRecvStream(stream)); 3112 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); 3117 } 3118 3119 // Tests for the actual WebRtc VoE library. 3120 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); 3127 delete channel; 3128 engine.Terminate(); 3129 3130 // Reinit to catch regression where VoiceEngineObserver reference is lost 3131 EXPECT_TRUE(engine.Init(rtc::Thread::Current())); 3132 engine.Terminate(); 3133 } 3134 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); 3140 size_t size = 0; 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); 3147 engine.Terminate(); 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: " 3153 << std::hex << ch; 3154 cleartext = (isprint(ch) || isspace(ch)); 3155 } 3156 EXPECT_TRUE(cleartext); 3157 } 3158 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())); 3168 engine.Terminate(); 3169 rtc::LogMessage::RemoveLogToStream(stream.get()); 3170 3171 size_t size = 0; 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")); 3176 } 3177 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); 3250 } 3251 } 3252 3253 engine.Terminate(); 3254 } 3255 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())); 3260 3261 cricket::VoiceMediaChannel* channels[32]; 3262 int num_channels = 0; 3263 3264 while (num_channels < ARRAY_SIZE(channels)) { 3265 cricket::VoiceMediaChannel* channel = engine.CreateChannel(); 3266 if (!channel) 3267 break; 3268 3269 channels[num_channels++] = channel; 3270 } 3271 3272 int expected = ARRAY_SIZE(channels); 3273 EXPECT_EQ(expected, num_channels); 3274 3275 while (num_channels > 0) { 3276 delete channels[--num_channels]; 3277 } 3278 3279 engine.Terminate(); 3280 } 3281 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())); 3288 } 3289 3290 #ifdef WIN32 3291 // Test our workarounds to WebRtc VoE' munging of the coinit count 3292 TEST(WebRtcVoiceEngineTest, CoInitialize) { 3293 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine(); 3294 3295 // Initial refcount should be 0. 3296 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED)); 3297 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(); 3303 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. 3307 CoUninitialize(); 3308 CoUninitialize(); 3309 delete engine; 3310 3311 // Ensure refcount is 0. 3312 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED)); 3313 CoUninitialize(); 3314 } 3315 #endif 3316 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; 3322 3323 EXPECT_TRUE(SetupEngine()); 3324 cricket::WebRtcVoiceMediaChannel* media_channel = 3325 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_); 3326 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(), 3327 kVieCh)); 3328 EXPECT_TRUE(media_channel->AddRecvStream( 3329 cricket::StreamParams::CreateLegacy(2))); 3330 int recv_ch = voe_.GetLastChannel(); 3331 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)); 3335 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)); 3342 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)); 3348 3349 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1)); 3350 } 3351 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; 3359 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(); 3369 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)); 3373 3374 // Register - should be enabled. 3375 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie1.engine(), 3376 kVieCh1)); 3377 EXPECT_EQ(vie1.network(), voe_.GetViENetwork(recv_ch)); 3378 EXPECT_EQ(kVieCh1, voe_.GetVideoChannel(recv_ch)); 3379 3380 // Re-register - should still be enabled. 3381 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie2.engine(), 3382 kVieCh2)); 3383 EXPECT_EQ(vie2.network(), voe_.GetViENetwork(recv_ch)); 3384 EXPECT_EQ(kVieCh2, voe_.GetVideoChannel(recv_ch)); 3385 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)); 3390 } 3391 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; 3397 3398 EXPECT_TRUE(SetupEngine()); 3399 cricket::WebRtcVoiceMediaChannel* media_channel = 3400 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_); 3401 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(), 3402 kVieCh)); 3403 cricket::AudioOptions options; 3404 options.combined_audio_video_bwe.Set(true); 3405 EXPECT_TRUE(media_channel->SetOptions(options)); 3406 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)); 3417 } 3418 3419 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1)); 3420 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])); 3424 } 3425 } 3426