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