1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/base/fakecpumonitor.h" 29 #include "talk/base/gunit.h" 30 #include "talk/base/logging.h" 31 #include "talk/base/scoped_ptr.h" 32 #include "talk/base/stream.h" 33 #include "talk/media/base/constants.h" 34 #include "talk/media/base/fakemediaprocessor.h" 35 #include "talk/media/base/fakenetworkinterface.h" 36 #include "talk/media/base/fakevideorenderer.h" 37 #include "talk/media/base/mediachannel.h" 38 #include "talk/media/base/testutils.h" 39 #include "talk/media/base/videoengine_unittest.h" 40 #include "talk/media/webrtc/fakewebrtcvideocapturemodule.h" 41 #include "talk/media/webrtc/fakewebrtcvideoengine.h" 42 #include "talk/media/webrtc/fakewebrtcvoiceengine.h" 43 #include "talk/media/webrtc/webrtcvideocapturer.h" 44 #include "talk/media/webrtc/webrtcvideoengine.h" 45 #include "talk/media/webrtc/webrtcvideoframe.h" 46 #include "talk/media/webrtc/webrtcvoiceengine.h" 47 #include "talk/session/media/mediasession.h" 48 #include "webrtc/system_wrappers/interface/trace.h" 49 50 // Tests for the WebRtcVideoEngine/VideoChannel code. 51 52 static const cricket::VideoCodec kVP8Codec720p(100, "VP8", 1280, 720, 30, 0); 53 static const cricket::VideoCodec kVP8Codec360p(100, "VP8", 640, 360, 30, 0); 54 static const cricket::VideoCodec kVP8Codec270p(100, "VP8", 480, 270, 30, 0); 55 static const cricket::VideoCodec kVP8Codec180p(100, "VP8", 320, 180, 30, 0); 56 57 static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0); 58 static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0); 59 static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0); 60 static const cricket::VideoCodec* const kVideoCodecs[] = { 61 &kVP8Codec, 62 &kRedCodec, 63 &kUlpFecCodec 64 }; 65 66 static const unsigned int kMinBandwidthKbps = 50; 67 static const unsigned int kStartBandwidthKbps = 300; 68 static const unsigned int kMaxBandwidthKbps = 2000; 69 70 static const unsigned int kNumberOfTemporalLayers = 1; 71 72 static const uint32 kSsrcs1[] = {1}; 73 static const uint32 kSsrcs2[] = {1, 2}; 74 static const uint32 kSsrcs3[] = {1, 2, 3}; 75 static const uint32 kRtxSsrc1[] = {4}; 76 static const uint32 kRtxSsrcs3[] = {4, 5, 6}; 77 78 79 class FakeViEWrapper : public cricket::ViEWrapper { 80 public: 81 explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine) 82 : cricket::ViEWrapper(engine, // base 83 engine, // codec 84 engine, // capture 85 engine, // network 86 engine, // render 87 engine, // rtp 88 engine, // image 89 engine) { // external decoder 90 } 91 }; 92 93 // Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine. 94 // Useful for testing failure paths. 95 class WebRtcVideoEngineTestFake : public testing::Test, 96 public sigslot::has_slots<> { 97 public: 98 WebRtcVideoEngineTestFake() 99 : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)), 100 cpu_monitor_(new talk_base::FakeCpuMonitor( 101 talk_base::Thread::Current())), 102 engine_(NULL, // cricket::WebRtcVoiceEngine 103 new FakeViEWrapper(&vie_), cpu_monitor_), 104 channel_(NULL), 105 voice_channel_(NULL), 106 last_error_(cricket::VideoMediaChannel::ERROR_NONE) { 107 } 108 bool SetupEngine() { 109 bool result = engine_.Init(talk_base::Thread::Current()); 110 if (result) { 111 channel_ = engine_.CreateChannel(voice_channel_); 112 channel_->SignalMediaError.connect(this, 113 &WebRtcVideoEngineTestFake::OnMediaError); 114 result = (channel_ != NULL); 115 } 116 return result; 117 } 118 void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) { 119 last_error_ = error; 120 } 121 bool SendI420Frame(int width, int height) { 122 if (NULL == channel_) { 123 return false; 124 } 125 cricket::WebRtcVideoFrame frame; 126 if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) { 127 return false; 128 } 129 cricket::FakeVideoCapturer capturer; 130 channel_->SendFrame(&capturer, &frame); 131 return true; 132 } 133 bool SendI420ScreencastFrame(int width, int height) { 134 return SendI420ScreencastFrameWithTimestamp(width, height, 0); 135 } 136 bool SendI420ScreencastFrameWithTimestamp( 137 int width, int height, int64 timestamp) { 138 if (NULL == channel_) { 139 return false; 140 } 141 cricket::WebRtcVideoFrame frame; 142 if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) { 143 return false; 144 } 145 cricket::FakeVideoCapturer capturer; 146 capturer.SetScreencast(true); 147 channel_->SendFrame(&capturer, &frame); 148 return true; 149 } 150 void VerifyVP8SendCodec(int channel_num, 151 unsigned int width, 152 unsigned int height, 153 unsigned int layers = 0, 154 unsigned int max_bitrate = kMaxBandwidthKbps, 155 unsigned int min_bitrate = kMinBandwidthKbps, 156 unsigned int start_bitrate = kStartBandwidthKbps, 157 unsigned int fps = 30, 158 unsigned int max_quantization = 0 159 ) { 160 webrtc::VideoCodec gcodec; 161 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 162 163 // Video codec properties. 164 EXPECT_EQ(webrtc::kVideoCodecVP8, gcodec.codecType); 165 EXPECT_STREQ("VP8", gcodec.plName); 166 EXPECT_EQ(100, gcodec.plType); 167 EXPECT_EQ(width, gcodec.width); 168 EXPECT_EQ(height, gcodec.height); 169 EXPECT_EQ(talk_base::_min(start_bitrate, max_bitrate), gcodec.startBitrate); 170 EXPECT_EQ(max_bitrate, gcodec.maxBitrate); 171 EXPECT_EQ(min_bitrate, gcodec.minBitrate); 172 EXPECT_EQ(fps, gcodec.maxFramerate); 173 // VP8 specific. 174 EXPECT_FALSE(gcodec.codecSpecific.VP8.pictureLossIndicationOn); 175 EXPECT_FALSE(gcodec.codecSpecific.VP8.feedbackModeOn); 176 EXPECT_EQ(webrtc::kComplexityNormal, gcodec.codecSpecific.VP8.complexity); 177 EXPECT_EQ(webrtc::kResilienceOff, gcodec.codecSpecific.VP8.resilience); 178 EXPECT_EQ(max_quantization, gcodec.qpMax); 179 } 180 virtual void TearDown() { 181 delete channel_; 182 engine_.Terminate(); 183 } 184 185 protected: 186 cricket::FakeWebRtcVideoEngine vie_; 187 cricket::FakeWebRtcVideoDecoderFactory decoder_factory_; 188 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_; 189 talk_base::FakeCpuMonitor* cpu_monitor_; 190 cricket::WebRtcVideoEngine engine_; 191 cricket::WebRtcVideoMediaChannel* channel_; 192 cricket::WebRtcVoiceMediaChannel* voice_channel_; 193 cricket::VideoMediaChannel::Error last_error_; 194 }; 195 196 // Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine. 197 class WebRtcVideoEngineTest 198 : public VideoEngineTest<cricket::WebRtcVideoEngine> { 199 protected: 200 typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base; 201 }; 202 class WebRtcVideoMediaChannelTest 203 : public VideoMediaChannelTest< 204 cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> { 205 protected: 206 typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine, 207 cricket::WebRtcVideoMediaChannel> Base; 208 virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; } 209 virtual void SetUp() { 210 Base::SetUp(); 211 } 212 virtual void TearDown() { 213 Base::TearDown(); 214 } 215 }; 216 217 ///////////////////////// 218 // Tests with fake ViE // 219 ///////////////////////// 220 221 // Tests that our stub library "works". 222 TEST_F(WebRtcVideoEngineTestFake, StartupShutdown) { 223 EXPECT_FALSE(vie_.IsInited()); 224 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 225 EXPECT_TRUE(vie_.IsInited()); 226 engine_.Terminate(); 227 } 228 229 // Tests that webrtc logs are logged when they should be. 230 TEST_F(WebRtcVideoEngineTest, WebRtcShouldLog) { 231 const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldLog"; 232 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 233 engine_.SetLogging(talk_base::LS_INFO, ""); 234 std::string str; 235 talk_base::StringStream stream(str); 236 talk_base::LogMessage::AddLogToStream(&stream, talk_base::LS_INFO); 237 EXPECT_EQ(talk_base::LS_INFO, talk_base::LogMessage::GetLogToStream(&stream)); 238 webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0, 239 webrtc_log); 240 EXPECT_TRUE_WAIT(std::string::npos != str.find(webrtc_log), 10); 241 talk_base::LogMessage::RemoveLogToStream(&stream); 242 } 243 244 // Tests that webrtc logs are not logged when they should't be. 245 TEST_F(WebRtcVideoEngineTest, WebRtcShouldNotLog) { 246 const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldNotLog"; 247 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 248 // WebRTC should never be logged lower than LS_INFO. 249 engine_.SetLogging(talk_base::LS_WARNING, ""); 250 std::string str; 251 talk_base::StringStream stream(str); 252 // Make sure that WebRTC is not logged, even at lowest severity 253 talk_base::LogMessage::AddLogToStream(&stream, talk_base::LS_SENSITIVE); 254 EXPECT_EQ(talk_base::LS_SENSITIVE, 255 talk_base::LogMessage::GetLogToStream(&stream)); 256 webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0, 257 webrtc_log); 258 talk_base::Thread::Current()->ProcessMessages(10); 259 EXPECT_EQ(std::string::npos, str.find(webrtc_log)); 260 talk_base::LogMessage::RemoveLogToStream(&stream); 261 } 262 263 // Tests that we can create and destroy a channel. 264 TEST_F(WebRtcVideoEngineTestFake, CreateChannel) { 265 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 266 channel_ = engine_.CreateChannel(voice_channel_); 267 EXPECT_TRUE(channel_ != NULL); 268 EXPECT_EQ(1, engine_.GetNumOfChannels()); 269 delete channel_; 270 channel_ = NULL; 271 EXPECT_EQ(0, engine_.GetNumOfChannels()); 272 } 273 274 // Tests that we properly handle failures in CreateChannel. 275 TEST_F(WebRtcVideoEngineTestFake, CreateChannelFail) { 276 vie_.set_fail_create_channel(true); 277 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 278 channel_ = engine_.CreateChannel(voice_channel_); 279 EXPECT_TRUE(channel_ == NULL); 280 } 281 282 // Tests that we properly handle failures in AllocateExternalCaptureDevice. 283 TEST_F(WebRtcVideoEngineTestFake, AllocateExternalCaptureDeviceFail) { 284 vie_.set_fail_alloc_capturer(true); 285 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 286 channel_ = engine_.CreateChannel(voice_channel_); 287 EXPECT_TRUE(channel_ == NULL); 288 } 289 290 // Test that we apply our default codecs properly. 291 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecs) { 292 EXPECT_TRUE(SetupEngine()); 293 int channel_num = vie_.GetLastChannel(); 294 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 295 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 296 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); 297 EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); 298 EXPECT_FALSE(vie_.GetNackStatus(channel_num)); 299 // TODO(juberti): Check RTCP, PLI, TMMBR. 300 } 301 302 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrate) { 303 EXPECT_TRUE(SetupEngine()); 304 int channel_num = vie_.GetLastChannel(); 305 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 306 codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; 307 codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; 308 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 309 310 VerifyVP8SendCodec( 311 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); 312 313 cricket::VideoCodec codec; 314 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 315 EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]); 316 EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]); 317 } 318 319 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrateInvalid) { 320 EXPECT_TRUE(SetupEngine()); 321 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 322 codecs[0].params[cricket::kCodecParamMinBitrate] = "30"; 323 codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; 324 EXPECT_FALSE(channel_->SetSendCodecs(codecs)); 325 } 326 327 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithLargeMinMaxBitrate) { 328 EXPECT_TRUE(SetupEngine()); 329 int channel_num = vie_.GetLastChannel(); 330 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 331 codecs[0].params[cricket::kCodecParamMinBitrate] = "1000"; 332 codecs[0].params[cricket::kCodecParamMaxBitrate] = "2000"; 333 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 334 335 VerifyVP8SendCodec( 336 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 2000, 1000, 337 1000); 338 } 339 340 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMaxQuantization) { 341 EXPECT_TRUE(SetupEngine()); 342 int channel_num = vie_.GetLastChannel(); 343 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 344 codecs[0].params[cricket::kCodecParamMaxQuantization] = "21"; 345 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 346 347 VerifyVP8SendCodec( 348 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 2000, 50, 300, 349 30, 21); 350 351 cricket::VideoCodec codec; 352 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 353 EXPECT_EQ("21", codec.params[cricket::kCodecParamMaxQuantization]); 354 } 355 356 TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithMaxBitrate) { 357 EXPECT_TRUE(SetupEngine()); 358 int channel_num = vie_.GetLastChannel(); 359 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 360 codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; 361 codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; 362 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 363 364 VerifyVP8SendCodec( 365 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); 366 367 // Verify that max bitrate doesn't change after SetOptions(). 368 cricket::VideoOptions options; 369 options.video_noise_reduction.Set(true); 370 EXPECT_TRUE(channel_->SetOptions(options)); 371 VerifyVP8SendCodec( 372 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); 373 374 options.video_noise_reduction.Set(false); 375 options.conference_mode.Set(false); 376 EXPECT_TRUE(channel_->SetOptions(options)); 377 VerifyVP8SendCodec( 378 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); 379 } 380 381 TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithLoweredBitrate) { 382 EXPECT_TRUE(SetupEngine()); 383 int channel_num = vie_.GetLastChannel(); 384 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 385 codecs[0].params[cricket::kCodecParamMinBitrate] = "50"; 386 codecs[0].params[cricket::kCodecParamMaxBitrate] = "100"; 387 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 388 389 VerifyVP8SendCodec( 390 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 100, 50, 100); 391 392 // Verify that min bitrate changes after SetOptions(). 393 cricket::VideoOptions options; 394 options.lower_min_bitrate.Set(true); 395 EXPECT_TRUE(channel_->SetOptions(options)); 396 VerifyVP8SendCodec( 397 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 100, 30, 100); 398 } 399 400 TEST_F(WebRtcVideoEngineTestFake, MaxBitrateResetWithConferenceMode) { 401 EXPECT_TRUE(SetupEngine()); 402 int channel_num = vie_.GetLastChannel(); 403 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 404 codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; 405 codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; 406 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 407 408 VerifyVP8SendCodec( 409 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); 410 411 cricket::VideoOptions options; 412 options.conference_mode.Set(true); 413 EXPECT_TRUE(channel_->SetOptions(options)); 414 options.conference_mode.Set(false); 415 EXPECT_TRUE(channel_->SetOptions(options)); 416 VerifyVP8SendCodec( 417 channel_num, kVP8Codec.width, kVP8Codec.height, 0, 418 kMaxBandwidthKbps, 10, 20); 419 } 420 421 // Verify the current send bitrate is used as start bitrate when reconfiguring 422 // the send codec. 423 TEST_F(WebRtcVideoEngineTestFake, StartSendBitrate) { 424 EXPECT_TRUE(SetupEngine()); 425 EXPECT_TRUE(channel_->AddSendStream( 426 cricket::StreamParams::CreateLegacy(1))); 427 int send_channel = vie_.GetLastChannel(); 428 cricket::VideoCodec codec(kVP8Codec); 429 std::vector<cricket::VideoCodec> codec_list; 430 codec_list.push_back(codec); 431 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 432 const unsigned int kVideoMaxSendBitrateKbps = 2000; 433 const unsigned int kVideoMinSendBitrateKbps = 50; 434 const unsigned int kVideoDefaultStartSendBitrateKbps = 300; 435 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 436 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 437 kVideoDefaultStartSendBitrateKbps); 438 EXPECT_EQ(0, vie_.StartSend(send_channel)); 439 440 // Increase the send bitrate and verify it is used as start bitrate. 441 const unsigned int kVideoSendBitrateBps = 768000; 442 vie_.SetSendBitrates(send_channel, kVideoSendBitrateBps, 0, 0); 443 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 444 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 445 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 446 kVideoSendBitrateBps / 1000); 447 448 // Never set a start bitrate higher than the max bitrate. 449 vie_.SetSendBitrates(send_channel, kVideoMaxSendBitrateKbps + 500, 0, 0); 450 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 451 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 452 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 453 kVideoDefaultStartSendBitrateKbps); 454 455 // Use the default start bitrate if the send bitrate is lower. 456 vie_.SetSendBitrates(send_channel, kVideoDefaultStartSendBitrateKbps - 50, 0, 457 0); 458 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 459 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 460 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 461 kVideoDefaultStartSendBitrateKbps); 462 } 463 464 465 // Test that we constrain send codecs properly. 466 TEST_F(WebRtcVideoEngineTestFake, ConstrainSendCodecs) { 467 EXPECT_TRUE(SetupEngine()); 468 int channel_num = vie_.GetLastChannel(); 469 470 // Set max settings of 640x400x30. 471 EXPECT_TRUE(engine_.SetDefaultEncoderConfig( 472 cricket::VideoEncoderConfig(kVP8Codec))); 473 474 // Send codec format bigger than max setting. 475 cricket::VideoCodec codec(kVP8Codec); 476 codec.width = 1280; 477 codec.height = 800; 478 codec.framerate = 60; 479 std::vector<cricket::VideoCodec> codec_list; 480 codec_list.push_back(codec); 481 482 // Set send codec and verify codec has been constrained. 483 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 484 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); 485 } 486 487 // Test that SetSendCodecs rejects bad format. 488 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadFormat) { 489 EXPECT_TRUE(SetupEngine()); 490 int channel_num = vie_.GetLastChannel(); 491 492 // Set w = 0. 493 cricket::VideoCodec codec(kVP8Codec); 494 codec.width = 0; 495 std::vector<cricket::VideoCodec> codec_list; 496 codec_list.push_back(codec); 497 498 // Verify SetSendCodecs failed and send codec is not changed on engine. 499 EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); 500 webrtc::VideoCodec gcodec; 501 // Set plType to something other than the value to test against ensuring 502 // that failure will happen if it is not changed. 503 gcodec.plType = 1; 504 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 505 EXPECT_EQ(0, gcodec.plType); 506 507 // Set h = 0. 508 codec_list[0].width = 640; 509 codec_list[0].height = 0; 510 511 // Verify SetSendCodecs failed and send codec is not changed on engine. 512 EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); 513 // Set plType to something other than the value to test against ensuring 514 // that failure will happen if it is not changed. 515 gcodec.plType = 1; 516 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 517 EXPECT_EQ(0, gcodec.plType); 518 } 519 520 // Test that SetSendCodecs rejects bad codec. 521 TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadCodec) { 522 EXPECT_TRUE(SetupEngine()); 523 int channel_num = vie_.GetLastChannel(); 524 525 // Set bad codec name. 526 cricket::VideoCodec codec(kVP8Codec); 527 codec.name = "bad"; 528 std::vector<cricket::VideoCodec> codec_list; 529 codec_list.push_back(codec); 530 531 // Verify SetSendCodecs failed and send codec is not changed on engine. 532 EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); 533 webrtc::VideoCodec gcodec; 534 // Set plType to something other than the value to test against ensuring 535 // that failure will happen if it is not changed. 536 gcodec.plType = 1; 537 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 538 EXPECT_EQ(0, gcodec.plType); 539 } 540 541 // Test that vie send codec is reset on new video frame size. 542 TEST_F(WebRtcVideoEngineTestFake, ResetVieSendCodecOnNewFrameSize) { 543 EXPECT_TRUE(SetupEngine()); 544 int channel_num = vie_.GetLastChannel(); 545 546 // Set send codec. 547 std::vector<cricket::VideoCodec> codec_list; 548 codec_list.push_back(kVP8Codec); 549 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 550 EXPECT_TRUE(channel_->AddSendStream( 551 cricket::StreamParams::CreateLegacy(123))); 552 EXPECT_TRUE(channel_->SetSend(true)); 553 554 // Capture a smaller frame and verify vie send codec has been reset to 555 // the new size. 556 SendI420Frame(kVP8Codec.width / 2, kVP8Codec.height / 2); 557 VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2); 558 559 // Capture a frame bigger than send_codec_ and verify vie send codec has been 560 // reset (and clipped) to send_codec_. 561 SendI420Frame(kVP8Codec.width * 2, kVP8Codec.height * 2); 562 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); 563 } 564 565 // Test that we set our inbound codecs properly. 566 TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) { 567 EXPECT_TRUE(SetupEngine()); 568 int channel_num = vie_.GetLastChannel(); 569 570 std::vector<cricket::VideoCodec> codecs; 571 codecs.push_back(kVP8Codec); 572 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 573 574 webrtc::VideoCodec wcodec; 575 EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(kVP8Codec, &wcodec)); 576 EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec)); 577 } 578 579 // Test that channel connects and disconnects external capturer correctly. 580 TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) { 581 EXPECT_TRUE(SetupEngine()); 582 int channel_num = vie_.GetLastChannel(); 583 584 EXPECT_EQ(1, vie_.GetNumCapturers()); 585 int capture_id = vie_.GetCaptureId(channel_num); 586 EXPECT_EQ(channel_num, vie_.GetCaptureChannelId(capture_id)); 587 588 // Delete the channel should disconnect the capturer. 589 delete channel_; 590 channel_ = NULL; 591 EXPECT_EQ(0, vie_.GetNumCapturers()); 592 } 593 594 // Test that channel adds and removes renderer correctly. 595 TEST_F(WebRtcVideoEngineTestFake, HasRenderer) { 596 EXPECT_TRUE(SetupEngine()); 597 int channel_num = vie_.GetLastChannel(); 598 599 EXPECT_TRUE(vie_.GetHasRenderer(channel_num)); 600 EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); 601 } 602 603 // Test that rtcp is enabled on the channel. 604 TEST_F(WebRtcVideoEngineTestFake, RtcpEnabled) { 605 EXPECT_TRUE(SetupEngine()); 606 int channel_num = vie_.GetLastChannel(); 607 EXPECT_EQ(webrtc::kRtcpCompound_RFC4585, vie_.GetRtcpStatus(channel_num)); 608 } 609 610 // Test that key frame request method is set on the channel. 611 TEST_F(WebRtcVideoEngineTestFake, KeyFrameRequestEnabled) { 612 EXPECT_TRUE(SetupEngine()); 613 int channel_num = vie_.GetLastChannel(); 614 EXPECT_EQ(webrtc::kViEKeyFrameRequestPliRtcp, 615 vie_.GetKeyFrameRequestMethod(channel_num)); 616 } 617 618 // Test that remb receive and send is enabled for the default channel in a 1:1 619 // call. 620 TEST_F(WebRtcVideoEngineTestFake, RembEnabled) { 621 EXPECT_TRUE(SetupEngine()); 622 int channel_num = vie_.GetLastChannel(); 623 EXPECT_TRUE(channel_->AddSendStream( 624 cricket::StreamParams::CreateLegacy(1))); 625 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 626 EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); 627 EXPECT_TRUE(channel_->SetSend(true)); 628 EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); 629 EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); 630 } 631 632 // When in conference mode, test that remb is enabled on a receive channel but 633 // not for the default channel and that it uses the default channel for sending 634 // remb packets. 635 TEST_F(WebRtcVideoEngineTestFake, RembEnabledOnReceiveChannels) { 636 EXPECT_TRUE(SetupEngine()); 637 int default_channel = vie_.GetLastChannel(); 638 cricket::VideoOptions options; 639 options.conference_mode.Set(true); 640 EXPECT_TRUE(channel_->SetOptions(options)); 641 EXPECT_TRUE(channel_->AddSendStream( 642 cricket::StreamParams::CreateLegacy(1))); 643 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 644 EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel)); 645 EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel)); 646 EXPECT_TRUE(channel_->SetSend(true)); 647 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 648 int new_channel_num = vie_.GetLastChannel(); 649 EXPECT_NE(default_channel, new_channel_num); 650 651 EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel)); 652 EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel)); 653 EXPECT_FALSE(vie_.GetRembStatusBwPartition(new_channel_num)); 654 EXPECT_TRUE(vie_.GetRembStatusContribute(new_channel_num)); 655 } 656 657 TEST_F(WebRtcVideoEngineTestFake, RecvStreamWithRtx) { 658 EXPECT_TRUE(SetupEngine()); 659 int default_channel = vie_.GetLastChannel(); 660 cricket::VideoOptions options; 661 options.conference_mode.Set(true); 662 EXPECT_TRUE(channel_->SetOptions(options)); 663 EXPECT_TRUE(channel_->AddSendStream( 664 cricket::CreateSimWithRtxStreamParams("cname", 665 MAKE_VECTOR(kSsrcs3), 666 MAKE_VECTOR(kRtxSsrcs3)))); 667 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 668 EXPECT_TRUE(channel_->SetSend(true)); 669 EXPECT_TRUE(channel_->AddRecvStream( 670 cricket::CreateSimWithRtxStreamParams("cname", 671 MAKE_VECTOR(kSsrcs1), 672 MAKE_VECTOR(kRtxSsrc1)))); 673 int new_channel_num = vie_.GetLastChannel(); 674 EXPECT_NE(default_channel, new_channel_num); 675 EXPECT_EQ(4, vie_.GetRemoteRtxSsrc(new_channel_num)); 676 } 677 678 TEST_F(WebRtcVideoEngineTestFake, RecvStreamNoRtx) { 679 EXPECT_TRUE(SetupEngine()); 680 int default_channel = vie_.GetLastChannel(); 681 cricket::VideoOptions options; 682 options.conference_mode.Set(true); 683 EXPECT_TRUE(channel_->SetOptions(options)); 684 EXPECT_TRUE(channel_->AddSendStream( 685 cricket::CreateSimWithRtxStreamParams("cname", 686 MAKE_VECTOR(kSsrcs3), 687 MAKE_VECTOR(kRtxSsrcs3)))); 688 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 689 EXPECT_TRUE(channel_->SetSend(true)); 690 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 691 int new_channel_num = vie_.GetLastChannel(); 692 EXPECT_NE(default_channel, new_channel_num); 693 EXPECT_EQ(-1, vie_.GetRemoteRtxSsrc(new_channel_num)); 694 } 695 696 // Test support for RTP timestamp offset header extension. 697 TEST_F(WebRtcVideoEngineTestFake, RtpTimestampOffsetHeaderExtensions) { 698 EXPECT_TRUE(SetupEngine()); 699 int channel_num = vie_.GetLastChannel(); 700 cricket::VideoOptions options; 701 options.conference_mode.Set(true); 702 EXPECT_TRUE(channel_->SetOptions(options)); 703 704 // Verify extensions are off by default. 705 EXPECT_EQ(0, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); 706 EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); 707 708 // Enable RTP timestamp extension. 709 const int id = 14; 710 std::vector<cricket::RtpHeaderExtension> extensions; 711 extensions.push_back(cricket::RtpHeaderExtension( 712 "urn:ietf:params:rtp-hdrext:toffset", id)); 713 714 // Verify the send extension id. 715 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 716 EXPECT_EQ(id, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); 717 718 // Remove the extension id. 719 std::vector<cricket::RtpHeaderExtension> empty_extensions; 720 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); 721 EXPECT_EQ(0, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); 722 723 // Verify receive extension id. 724 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 725 EXPECT_EQ(id, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); 726 727 // Add a new receive stream and verify the extension is set. 728 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); 729 int new_channel_num = vie_.GetLastChannel(); 730 EXPECT_NE(channel_num, new_channel_num); 731 EXPECT_EQ(id, vie_.GetReceiveRtpTimestampOffsetExtensionId(new_channel_num)); 732 733 // Remove the extension id. 734 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions)); 735 EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); 736 EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(new_channel_num)); 737 } 738 739 // Test support for absolute send time header extension. 740 TEST_F(WebRtcVideoEngineTestFake, AbsoluteSendTimeHeaderExtensions) { 741 EXPECT_TRUE(SetupEngine()); 742 int channel_num = vie_.GetLastChannel(); 743 cricket::VideoOptions options; 744 options.conference_mode.Set(true); 745 EXPECT_TRUE(channel_->SetOptions(options)); 746 747 // Verify extensions are off by default. 748 EXPECT_EQ(0, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); 749 EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); 750 751 // Enable RTP timestamp extension. 752 const int id = 12; 753 std::vector<cricket::RtpHeaderExtension> extensions; 754 extensions.push_back(cricket::RtpHeaderExtension( 755 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", id)); 756 757 // Verify the send extension id. 758 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 759 EXPECT_EQ(id, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); 760 761 // Remove the extension id. 762 std::vector<cricket::RtpHeaderExtension> empty_extensions; 763 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); 764 EXPECT_EQ(0, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); 765 766 // Verify receive extension id. 767 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 768 EXPECT_EQ(id, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); 769 770 // Add a new receive stream and verify the extension is set. 771 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); 772 int new_channel_num = vie_.GetLastChannel(); 773 EXPECT_NE(channel_num, new_channel_num); 774 EXPECT_EQ(id, vie_.GetReceiveAbsoluteSendTimeExtensionId(new_channel_num)); 775 776 // Remove the extension id. 777 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions)); 778 EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); 779 EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(new_channel_num)); 780 } 781 782 TEST_F(WebRtcVideoEngineTestFake, LeakyBucketTest) { 783 EXPECT_TRUE(SetupEngine()); 784 785 // Verify this is off by default. 786 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); 787 int first_send_channel = vie_.GetLastChannel(); 788 EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); 789 790 // Enable the experiment and verify. 791 cricket::VideoOptions options; 792 options.conference_mode.Set(true); 793 options.video_leaky_bucket.Set(true); 794 EXPECT_TRUE(channel_->SetOptions(options)); 795 EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); 796 797 // Add a receive channel and verify leaky bucket isn't enabled. 798 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); 799 int recv_channel_num = vie_.GetLastChannel(); 800 EXPECT_NE(first_send_channel, recv_channel_num); 801 EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(recv_channel_num)); 802 803 // Add a new send stream and verify leaky bucket is enabled from start. 804 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3))); 805 int second_send_channel = vie_.GetLastChannel(); 806 EXPECT_NE(first_send_channel, second_send_channel); 807 EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(second_send_channel)); 808 } 809 810 TEST_F(WebRtcVideoEngineTestFake, BufferedModeLatency) { 811 EXPECT_TRUE(SetupEngine()); 812 813 // Verify this is off by default. 814 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); 815 int first_send_channel = vie_.GetLastChannel(); 816 EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); 817 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); 818 819 // Enable the experiment and verify. The default channel will have both 820 // sender and receiver buffered mode enabled. 821 cricket::VideoOptions options; 822 options.conference_mode.Set(true); 823 options.buffered_mode_latency.Set(100); 824 EXPECT_TRUE(channel_->SetOptions(options)); 825 EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); 826 EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); 827 828 // Add a receive channel and verify sender buffered mode isn't enabled. 829 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); 830 int recv_channel_num = vie_.GetLastChannel(); 831 EXPECT_NE(first_send_channel, recv_channel_num); 832 EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num)); 833 EXPECT_EQ(100, vie_.GetReceiverTargetDelay(recv_channel_num)); 834 835 // Add a new send stream and verify sender buffered mode is enabled. 836 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3))); 837 int second_send_channel = vie_.GetLastChannel(); 838 EXPECT_NE(first_send_channel, second_send_channel); 839 EXPECT_EQ(100, vie_.GetSenderTargetDelay(second_send_channel)); 840 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel)); 841 842 // Disable sender buffered mode and verify. 843 options.buffered_mode_latency.Set(cricket::kBufferedModeDisabled); 844 EXPECT_TRUE(channel_->SetOptions(options)); 845 EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); 846 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); 847 EXPECT_EQ(0, vie_.GetSenderTargetDelay(second_send_channel)); 848 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel)); 849 EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num)); 850 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(recv_channel_num)); 851 } 852 853 TEST_F(WebRtcVideoEngineTestFake, AdditiveVideoOptions) { 854 EXPECT_TRUE(SetupEngine()); 855 856 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); 857 int first_send_channel = vie_.GetLastChannel(); 858 EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); 859 EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); 860 861 cricket::VideoOptions options1; 862 options1.buffered_mode_latency.Set(100); 863 EXPECT_TRUE(channel_->SetOptions(options1)); 864 EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); 865 EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); 866 EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); 867 868 cricket::VideoOptions options2; 869 options2.video_leaky_bucket.Set(true); 870 EXPECT_TRUE(channel_->SetOptions(options2)); 871 EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); 872 // The buffered_mode_latency still takes effect. 873 EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); 874 EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); 875 876 options1.buffered_mode_latency.Set(50); 877 EXPECT_TRUE(channel_->SetOptions(options1)); 878 EXPECT_EQ(50, vie_.GetSenderTargetDelay(first_send_channel)); 879 EXPECT_EQ(50, vie_.GetReceiverTargetDelay(first_send_channel)); 880 // The video_leaky_bucket still takes effect. 881 EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); 882 } 883 884 // Test that AddRecvStream doesn't create new channel for 1:1 call. 885 TEST_F(WebRtcVideoEngineTestFake, AddRecvStream1On1) { 886 EXPECT_TRUE(SetupEngine()); 887 int channel_num = vie_.GetLastChannel(); 888 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 889 EXPECT_EQ(channel_num, vie_.GetLastChannel()); 890 } 891 892 // Test that AddRecvStream doesn't change remb for 1:1 call. 893 TEST_F(WebRtcVideoEngineTestFake, NoRembChangeAfterAddRecvStream) { 894 EXPECT_TRUE(SetupEngine()); 895 int channel_num = vie_.GetLastChannel(); 896 EXPECT_TRUE(channel_->AddSendStream( 897 cricket::StreamParams::CreateLegacy(1))); 898 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 899 EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); 900 EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); 901 EXPECT_TRUE(channel_->SetSend(true)); 902 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 903 EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); 904 EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); 905 } 906 907 // Verify default REMB setting and that it can be turned on and off. 908 TEST_F(WebRtcVideoEngineTestFake, RembOnOff) { 909 EXPECT_TRUE(SetupEngine()); 910 int channel_num = vie_.GetLastChannel(); 911 // Verify REMB sending is always off by default. 912 EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num)); 913 914 // Verify that REMB is turned on when setting default codecs since the 915 // default codecs have REMB enabled. 916 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 917 EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); 918 919 // Verify that REMB is turned off when codecs without REMB are set. 920 std::vector<cricket::VideoCodec> codecs = engine_.codecs(); 921 // Clearing the codecs' FeedbackParams and setting send codecs should disable 922 // REMB. 923 for (std::vector<cricket::VideoCodec>::iterator iter = codecs.begin(); 924 iter != codecs.end(); ++iter) { 925 // Intersecting with empty will clear the FeedbackParams. 926 cricket::FeedbackParams empty_params; 927 iter->feedback_params.Intersect(empty_params); 928 EXPECT_TRUE(iter->feedback_params.params().empty()); 929 } 930 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 931 EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num)); 932 } 933 934 // Test that nack is enabled on the channel if we don't offer red/fec. 935 TEST_F(WebRtcVideoEngineTestFake, NackEnabled) { 936 EXPECT_TRUE(SetupEngine()); 937 int channel_num = vie_.GetLastChannel(); 938 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 939 codecs.resize(1); // toss out red and ulpfec 940 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 941 EXPECT_TRUE(vie_.GetNackStatus(channel_num)); 942 } 943 944 // Test that we enable hybrid NACK FEC mode. 945 TEST_F(WebRtcVideoEngineTestFake, HybridNackFec) { 946 EXPECT_TRUE(SetupEngine()); 947 int channel_num = vie_.GetLastChannel(); 948 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); 949 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 950 EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); 951 EXPECT_FALSE(vie_.GetNackStatus(channel_num)); 952 } 953 954 // Test that we enable hybrid NACK FEC mode when calling SetSendCodecs and 955 // SetReceiveCodecs in reversed order. 956 TEST_F(WebRtcVideoEngineTestFake, HybridNackFecReversedOrder) { 957 EXPECT_TRUE(SetupEngine()); 958 int channel_num = vie_.GetLastChannel(); 959 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 960 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); 961 EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); 962 EXPECT_FALSE(vie_.GetNackStatus(channel_num)); 963 } 964 965 // Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if 966 // red/fec is offered as receive codec. 967 TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInterop) { 968 EXPECT_TRUE(SetupEngine()); 969 int channel_num = vie_.GetLastChannel(); 970 std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs()); 971 std::vector<cricket::VideoCodec> send_codecs(engine_.codecs()); 972 // Only add VP8 as send codec. 973 send_codecs.resize(1); 974 EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs)); 975 EXPECT_TRUE(channel_->SetSendCodecs(send_codecs)); 976 EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num)); 977 EXPECT_TRUE(vie_.GetNackStatus(channel_num)); 978 } 979 980 // Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if 981 // red/fec is offered as receive codec. Call order reversed compared to 982 // VideoProtectionInterop. 983 TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInteropReversed) { 984 EXPECT_TRUE(SetupEngine()); 985 int channel_num = vie_.GetLastChannel(); 986 std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs()); 987 std::vector<cricket::VideoCodec> send_codecs(engine_.codecs()); 988 // Only add VP8 as send codec. 989 send_codecs.resize(1); 990 EXPECT_TRUE(channel_->SetSendCodecs(send_codecs)); 991 EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs)); 992 EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num)); 993 EXPECT_TRUE(vie_.GetNackStatus(channel_num)); 994 } 995 996 // Test that NACK, not hybrid mode, is enabled in conference mode. 997 TEST_F(WebRtcVideoEngineTestFake, HybridNackFecConference) { 998 EXPECT_TRUE(SetupEngine()); 999 // Setup the send channel. 1000 int send_channel_num = vie_.GetLastChannel(); 1001 cricket::VideoOptions options; 1002 options.conference_mode.Set(true); 1003 EXPECT_TRUE(channel_->SetOptions(options)); 1004 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); 1005 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 1006 EXPECT_FALSE(vie_.GetHybridNackFecStatus(send_channel_num)); 1007 EXPECT_TRUE(vie_.GetNackStatus(send_channel_num)); 1008 // Add a receive stream. 1009 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 1010 int receive_channel_num = vie_.GetLastChannel(); 1011 EXPECT_FALSE(vie_.GetHybridNackFecStatus(receive_channel_num)); 1012 EXPECT_TRUE(vie_.GetNackStatus(receive_channel_num)); 1013 } 1014 1015 // Test that when AddRecvStream in conference mode, a new channel is created 1016 // for receiving. And the new channel's "original channel" is the send channel. 1017 TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamConference) { 1018 EXPECT_TRUE(SetupEngine()); 1019 // Setup the send channel. 1020 int send_channel_num = vie_.GetLastChannel(); 1021 cricket::VideoOptions options; 1022 options.conference_mode.Set(true); 1023 EXPECT_TRUE(channel_->SetOptions(options)); 1024 // Add a receive stream. 1025 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 1026 int receive_channel_num = vie_.GetLastChannel(); 1027 EXPECT_EQ(send_channel_num, vie_.GetOriginalChannelId(receive_channel_num)); 1028 EXPECT_TRUE(channel_->RemoveRecvStream(1)); 1029 EXPECT_FALSE(vie_.IsChannel(receive_channel_num)); 1030 } 1031 1032 // Test that we can create a channel and start/stop rendering out on it. 1033 TEST_F(WebRtcVideoEngineTestFake, SetRender) { 1034 EXPECT_TRUE(SetupEngine()); 1035 int channel_num = vie_.GetLastChannel(); 1036 1037 // Verify we can start/stop/start/stop rendering. 1038 EXPECT_TRUE(channel_->SetRender(true)); 1039 EXPECT_TRUE(vie_.GetRenderStarted(channel_num)); 1040 EXPECT_TRUE(channel_->SetRender(false)); 1041 EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); 1042 EXPECT_TRUE(channel_->SetRender(true)); 1043 EXPECT_TRUE(vie_.GetRenderStarted(channel_num)); 1044 EXPECT_TRUE(channel_->SetRender(false)); 1045 EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); 1046 } 1047 1048 // Test that we can create a channel and start/stop sending out on it. 1049 TEST_F(WebRtcVideoEngineTestFake, SetSend) { 1050 EXPECT_TRUE(SetupEngine()); 1051 int channel_num = vie_.GetLastChannel(); 1052 1053 // Set send codecs on the channel. 1054 std::vector<cricket::VideoCodec> codecs; 1055 codecs.push_back(kVP8Codec); 1056 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1057 EXPECT_TRUE(channel_->AddSendStream( 1058 cricket::StreamParams::CreateLegacy(123))); 1059 1060 // Verify we can start/stop/start/stop sending. 1061 EXPECT_TRUE(channel_->SetSend(true)); 1062 EXPECT_TRUE(vie_.GetSend(channel_num)); 1063 EXPECT_TRUE(channel_->SetSend(false)); 1064 EXPECT_FALSE(vie_.GetSend(channel_num)); 1065 EXPECT_TRUE(channel_->SetSend(true)); 1066 EXPECT_TRUE(vie_.GetSend(channel_num)); 1067 EXPECT_TRUE(channel_->SetSend(false)); 1068 EXPECT_FALSE(vie_.GetSend(channel_num)); 1069 } 1070 1071 // Test that we set bandwidth properly when using full auto bandwidth mode. 1072 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) { 1073 EXPECT_TRUE(SetupEngine()); 1074 int channel_num = vie_.GetLastChannel(); 1075 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 1076 EXPECT_TRUE(channel_->SetSendBandwidth(true, cricket::kAutoBandwidth)); 1077 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); 1078 } 1079 1080 // Test that we set bandwidth properly when using auto with upper bound. 1081 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAutoCapped) { 1082 EXPECT_TRUE(SetupEngine()); 1083 int channel_num = vie_.GetLastChannel(); 1084 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 1085 EXPECT_TRUE(channel_->SetSendBandwidth(true, 768000)); 1086 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 768U); 1087 } 1088 1089 // Test that we set bandwidth properly when using a fixed bandwidth. 1090 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthFixed) { 1091 EXPECT_TRUE(SetupEngine()); 1092 int channel_num = vie_.GetLastChannel(); 1093 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 1094 EXPECT_TRUE(channel_->SetSendBandwidth(false, 768000)); 1095 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 1096 768U, 768U, 768U); 1097 } 1098 1099 // Test that SetSendBandwidth is ignored in conference mode. 1100 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthInConference) { 1101 EXPECT_TRUE(SetupEngine()); 1102 int channel_num = vie_.GetLastChannel(); 1103 cricket::VideoOptions options; 1104 options.conference_mode.Set(true); 1105 EXPECT_TRUE(channel_->SetOptions(options)); 1106 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 1107 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); 1108 1109 // Set send bandwidth. 1110 EXPECT_TRUE(channel_->SetSendBandwidth(false, 768000)); 1111 1112 // Verify bitrate not changed. 1113 webrtc::VideoCodec gcodec; 1114 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 1115 EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate); 1116 EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate); 1117 EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate); 1118 EXPECT_NE(768U, gcodec.minBitrate); 1119 EXPECT_NE(768U, gcodec.startBitrate); 1120 EXPECT_NE(768U, gcodec.maxBitrate); 1121 } 1122 1123 // Test that sending screencast frames doesn't change bitrate. 1124 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthScreencast) { 1125 EXPECT_TRUE(SetupEngine()); 1126 int channel_num = vie_.GetLastChannel(); 1127 1128 // Set send codec. 1129 cricket::VideoCodec codec(kVP8Codec); 1130 std::vector<cricket::VideoCodec> codec_list; 1131 codec_list.push_back(codec); 1132 EXPECT_TRUE(channel_->AddSendStream( 1133 cricket::StreamParams::CreateLegacy(123))); 1134 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 1135 EXPECT_TRUE(channel_->SetSendBandwidth(false, 111000)); 1136 EXPECT_TRUE(channel_->SetSend(true)); 1137 1138 SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height); 1139 VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 1140 111, 111, 111); 1141 } 1142 1143 1144 // Test SetSendSsrc. 1145 TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAndCname) { 1146 EXPECT_TRUE(SetupEngine()); 1147 int channel_num = vie_.GetLastChannel(); 1148 1149 cricket::StreamParams stream; 1150 stream.ssrcs.push_back(1234); 1151 stream.cname = "cname"; 1152 channel_->AddSendStream(stream); 1153 1154 unsigned int ssrc = 0; 1155 EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc)); 1156 EXPECT_EQ(1234U, ssrc); 1157 EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num)); 1158 1159 char rtcp_cname[256]; 1160 EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname)); 1161 EXPECT_STREQ("cname", rtcp_cname); 1162 } 1163 1164 1165 // Test that the local SSRC is the same on sending and receiving channels if the 1166 // receive channel is created before the send channel. 1167 TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) { 1168 EXPECT_TRUE(SetupEngine()); 1169 1170 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 1171 int receive_channel_num = vie_.GetLastChannel(); 1172 cricket::StreamParams stream = cricket::StreamParams::CreateLegacy(1234); 1173 EXPECT_TRUE(channel_->AddSendStream(stream)); 1174 int send_channel_num = vie_.GetLastChannel(); 1175 unsigned int ssrc = 0; 1176 EXPECT_EQ(0, vie_.GetLocalSSRC(send_channel_num, ssrc)); 1177 EXPECT_EQ(1234U, ssrc); 1178 EXPECT_EQ(1, vie_.GetNumSsrcs(send_channel_num)); 1179 ssrc = 0; 1180 EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_num, ssrc)); 1181 EXPECT_EQ(1234U, ssrc); 1182 EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_num)); 1183 } 1184 1185 1186 // Test SetOptions with denoising flag. 1187 TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithDenoising) { 1188 EXPECT_TRUE(SetupEngine()); 1189 EXPECT_EQ(1, vie_.GetNumCapturers()); 1190 int channel_num = vie_.GetLastChannel(); 1191 int capture_id = vie_.GetCaptureId(channel_num); 1192 // Set send codecs on the channel. 1193 std::vector<cricket::VideoCodec> codecs; 1194 codecs.push_back(kVP8Codec); 1195 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1196 1197 // Set options with OPT_VIDEO_NOISE_REDUCTION flag. 1198 cricket::VideoOptions options; 1199 options.video_noise_reduction.Set(true); 1200 EXPECT_TRUE(channel_->SetOptions(options)); 1201 1202 // Verify capture has denoising turned on. 1203 webrtc::VideoCodec send_codec; 1204 memset(&send_codec, 0, sizeof(send_codec)); // avoid uninitialized warning 1205 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec)); 1206 EXPECT_TRUE(send_codec.codecSpecific.VP8.denoisingOn); 1207 EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id)); 1208 1209 // Set options back to zero. 1210 options.video_noise_reduction.Set(false); 1211 EXPECT_TRUE(channel_->SetOptions(options)); 1212 1213 // Verify capture has denoising turned off. 1214 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec)); 1215 EXPECT_FALSE(send_codec.codecSpecific.VP8.denoisingOn); 1216 EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id)); 1217 } 1218 1219 TEST_F(WebRtcVideoEngineTestFake, MultipleSendStreamsWithOneCapturer) { 1220 EXPECT_TRUE(SetupEngine()); 1221 1222 // Start the capturer 1223 cricket::FakeVideoCapturer capturer; 1224 cricket::VideoFormat capture_format_vga = cricket::VideoFormat(640, 480, 1225 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); 1226 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_vga)); 1227 1228 // Add send streams and connect the capturer 1229 for (unsigned int i = 0; i < sizeof(kSsrcs2)/sizeof(kSsrcs2[0]); ++i) { 1230 EXPECT_TRUE(channel_->AddSendStream( 1231 cricket::StreamParams::CreateLegacy(kSsrcs2[i]))); 1232 // Register the capturer to the ssrc. 1233 EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[i], &capturer)); 1234 } 1235 1236 const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs2[0]); 1237 ASSERT_NE(-1, channel0); 1238 const int channel1 = vie_.GetChannelFromLocalSsrc(kSsrcs2[1]); 1239 ASSERT_NE(-1, channel1); 1240 ASSERT_NE(channel0, channel1); 1241 1242 // Set send codec. 1243 std::vector<cricket::VideoCodec> codecs; 1244 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0); 1245 codecs.push_back(send_codec); 1246 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1247 1248 EXPECT_TRUE(capturer.CaptureFrame()); 1249 EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0)); 1250 EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel1)); 1251 1252 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[0])); 1253 EXPECT_TRUE(capturer.CaptureFrame()); 1254 // channel0 is the default channel, so it won't be deleted. 1255 // But it should be disconnected from the capturer. 1256 EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0)); 1257 EXPECT_EQ(2, vie_.GetIncomingFrameNum(channel1)); 1258 1259 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[1])); 1260 EXPECT_TRUE(capturer.CaptureFrame()); 1261 EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0)); 1262 // channel1 has already been deleted. 1263 EXPECT_EQ(-1, vie_.GetIncomingFrameNum(channel1)); 1264 } 1265 1266 1267 // Disabled since its flaky: b/11288120 1268 TEST_F(WebRtcVideoEngineTestFake, DISABLED_SendReceiveBitratesStats) { 1269 EXPECT_TRUE(SetupEngine()); 1270 cricket::VideoOptions options; 1271 options.conference_mode.Set(true); 1272 EXPECT_TRUE(channel_->SetOptions(options)); 1273 EXPECT_TRUE(channel_->AddSendStream( 1274 cricket::StreamParams::CreateLegacy(1))); 1275 int send_channel = vie_.GetLastChannel(); 1276 cricket::VideoCodec codec(kVP8Codec720p); 1277 std::vector<cricket::VideoCodec> codec_list; 1278 codec_list.push_back(codec); 1279 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 1280 1281 EXPECT_TRUE(channel_->AddRecvStream( 1282 cricket::StreamParams::CreateLegacy(2))); 1283 int first_receive_channel = vie_.GetLastChannel(); 1284 EXPECT_NE(send_channel, first_receive_channel); 1285 EXPECT_TRUE(channel_->AddRecvStream( 1286 cricket::StreamParams::CreateLegacy(3))); 1287 int second_receive_channel = vie_.GetLastChannel(); 1288 EXPECT_NE(first_receive_channel, second_receive_channel); 1289 1290 cricket::VideoMediaInfo info; 1291 EXPECT_TRUE(channel_->GetStats(&info)); 1292 ASSERT_EQ(1U, info.bw_estimations.size()); 1293 ASSERT_EQ(0, info.bw_estimations[0].actual_enc_bitrate); 1294 ASSERT_EQ(0, info.bw_estimations[0].transmit_bitrate); 1295 ASSERT_EQ(0, info.bw_estimations[0].retransmit_bitrate); 1296 ASSERT_EQ(0, info.bw_estimations[0].available_send_bandwidth); 1297 ASSERT_EQ(0, info.bw_estimations[0].available_recv_bandwidth); 1298 ASSERT_EQ(0, info.bw_estimations[0].target_enc_bitrate); 1299 1300 // Start sending and receiving on one of the channels and verify bitrates. 1301 EXPECT_EQ(0, vie_.StartSend(send_channel)); 1302 int send_video_bitrate = 800; 1303 int send_fec_bitrate = 100; 1304 int send_nack_bitrate = 20; 1305 int send_total_bitrate = send_video_bitrate + send_fec_bitrate + 1306 send_nack_bitrate; 1307 int send_bandwidth = 950; 1308 vie_.SetSendBitrates(send_channel, send_video_bitrate, send_fec_bitrate, 1309 send_nack_bitrate); 1310 vie_.SetSendBandwidthEstimate(send_channel, send_bandwidth); 1311 1312 EXPECT_EQ(0, vie_.StartReceive(first_receive_channel)); 1313 int first_channel_receive_bandwidth = 600; 1314 vie_.SetReceiveBandwidthEstimate(first_receive_channel, 1315 first_channel_receive_bandwidth); 1316 1317 info.Clear(); 1318 EXPECT_TRUE(channel_->GetStats(&info)); 1319 ASSERT_EQ(1U, info.bw_estimations.size()); 1320 ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate); 1321 ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate); 1322 ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate); 1323 ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth); 1324 ASSERT_EQ(first_channel_receive_bandwidth, 1325 info.bw_estimations[0].available_recv_bandwidth); 1326 ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate); 1327 1328 // Start receiving on the second channel and verify received rate. 1329 EXPECT_EQ(0, vie_.StartReceive(second_receive_channel)); 1330 int second_channel_receive_bandwidth = 100; 1331 vie_.SetReceiveBandwidthEstimate(second_receive_channel, 1332 second_channel_receive_bandwidth); 1333 1334 info.Clear(); 1335 EXPECT_TRUE(channel_->GetStats(&info)); 1336 ASSERT_EQ(1U, info.bw_estimations.size()); 1337 ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate); 1338 ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate); 1339 ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate); 1340 ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth); 1341 ASSERT_EQ(first_channel_receive_bandwidth + second_channel_receive_bandwidth, 1342 info.bw_estimations[0].available_recv_bandwidth); 1343 ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate); 1344 } 1345 1346 TEST_F(WebRtcVideoEngineTestFake, TestSetAdaptInputToCpuUsage) { 1347 EXPECT_TRUE(SetupEngine()); 1348 cricket::VideoOptions options_in, options_out; 1349 bool cpu_adapt = false; 1350 channel_->SetOptions(options_in); 1351 EXPECT_TRUE(channel_->GetOptions(&options_out)); 1352 EXPECT_FALSE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt)); 1353 // Set adapt input CPU usage option. 1354 options_in.adapt_input_to_cpu_usage.Set(true); 1355 EXPECT_TRUE(channel_->SetOptions(options_in)); 1356 EXPECT_TRUE(channel_->GetOptions(&options_out)); 1357 EXPECT_TRUE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt)); 1358 EXPECT_TRUE(cpu_adapt); 1359 } 1360 1361 TEST_F(WebRtcVideoEngineTestFake, TestSetCpuThreshold) { 1362 EXPECT_TRUE(SetupEngine()); 1363 float low, high; 1364 cricket::VideoOptions options_in, options_out; 1365 // Verify that initial values are set. 1366 EXPECT_TRUE(channel_->GetOptions(&options_out)); 1367 EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); 1368 EXPECT_EQ(low, 0.65f); 1369 EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); 1370 EXPECT_EQ(high, 0.85f); 1371 // Set new CPU threshold values. 1372 options_in.system_low_adaptation_threshhold.Set(0.45f); 1373 options_in.system_high_adaptation_threshhold.Set(0.95f); 1374 EXPECT_TRUE(channel_->SetOptions(options_in)); 1375 EXPECT_TRUE(channel_->GetOptions(&options_out)); 1376 EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); 1377 EXPECT_EQ(low, 0.45f); 1378 EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); 1379 EXPECT_EQ(high, 0.95f); 1380 } 1381 1382 TEST_F(WebRtcVideoEngineTestFake, TestSetInvalidCpuThreshold) { 1383 EXPECT_TRUE(SetupEngine()); 1384 float low, high; 1385 cricket::VideoOptions options_in, options_out; 1386 // Valid range is [0, 1]. 1387 options_in.system_low_adaptation_threshhold.Set(-1.5f); 1388 options_in.system_high_adaptation_threshhold.Set(1.5f); 1389 EXPECT_TRUE(channel_->SetOptions(options_in)); 1390 EXPECT_TRUE(channel_->GetOptions(&options_out)); 1391 EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); 1392 EXPECT_EQ(low, 0.0f); 1393 EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); 1394 EXPECT_EQ(high, 1.0f); 1395 } 1396 1397 1398 ///////////////////////// 1399 // Tests with real ViE // 1400 ///////////////////////// 1401 1402 // Tests that we can find codecs by name or id. 1403 TEST_F(WebRtcVideoEngineTest, FindCodec) { 1404 // We should not need to init engine in order to get codecs. 1405 const std::vector<cricket::VideoCodec>& c = engine_.codecs(); 1406 EXPECT_EQ(4U, c.size()); 1407 1408 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); 1409 EXPECT_TRUE(engine_.FindCodec(vp8)); 1410 1411 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0); 1412 EXPECT_TRUE(engine_.FindCodec(vp8)); 1413 1414 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50); 1415 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref)); 1416 1417 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0); 1418 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id)); 1419 vp8_diff_id.id = 97; 1420 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id)); 1421 1422 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0); 1423 EXPECT_FALSE(engine_.FindCodec(vp8_diff_res)); 1424 1425 // PeerConnection doesn't negotiate the resolution at this point. 1426 // Test that FindCodec can handle the case when width/height is 0. 1427 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0); 1428 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res)); 1429 1430 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0); 1431 EXPECT_TRUE(engine_.FindCodec(red)); 1432 1433 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0); 1434 EXPECT_TRUE(engine_.FindCodec(red)); 1435 1436 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0); 1437 EXPECT_TRUE(engine_.FindCodec(fec)); 1438 1439 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0); 1440 EXPECT_TRUE(engine_.FindCodec(fec)); 1441 1442 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0); 1443 EXPECT_TRUE(engine_.FindCodec(rtx)); 1444 } 1445 1446 TEST_F(WebRtcVideoEngineTest, RtxCodecHasAptSet) { 1447 std::vector<cricket::VideoCodec>::const_iterator it; 1448 bool apt_checked = false; 1449 for (it = engine_.codecs().begin(); it != engine_.codecs().end(); ++it) { 1450 if (_stricmp(cricket::kRtxCodecName, it->name.c_str()) && it->id != 96) { 1451 continue; 1452 } 1453 int apt; 1454 EXPECT_TRUE(it->GetParam("apt", &apt)); 1455 EXPECT_EQ(100, apt); 1456 apt_checked = true; 1457 } 1458 EXPECT_TRUE(apt_checked); 1459 } 1460 1461 TEST_F(WebRtcVideoEngineTest, StartupShutdown) { 1462 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 1463 engine_.Terminate(); 1464 } 1465 1466 TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec) 1467 TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec) 1468 1469 TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec) 1470 TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec) 1471 1472 // TODO(juberti): Figure out why ViE is munging the COM refcount. 1473 #ifdef WIN32 1474 TEST_F(WebRtcVideoEngineTest, DISABLED_CheckCoInitialize) { 1475 Base::CheckCoInitialize(); 1476 } 1477 #endif 1478 1479 TEST_F(WebRtcVideoEngineTest, CreateChannel) { 1480 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); 1481 cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL); 1482 EXPECT_TRUE(channel != NULL); 1483 delete channel; 1484 } 1485 1486 TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecs) { 1487 std::vector<cricket::VideoCodec> codecs; 1488 codecs.push_back(kVP8Codec); 1489 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1490 } 1491 TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsWrongPayloadType) { 1492 std::vector<cricket::VideoCodec> codecs; 1493 codecs.push_back(kVP8Codec); 1494 codecs[0].id = 99; 1495 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1496 } 1497 TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsUnsupportedCodec) { 1498 std::vector<cricket::VideoCodec> codecs; 1499 codecs.push_back(kVP8Codec); 1500 codecs.push_back(cricket::VideoCodec(101, "VP1", 640, 400, 30, 0)); 1501 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); 1502 } 1503 1504 TEST_F(WebRtcVideoMediaChannelTest, SetSend) { 1505 Base::SetSend(); 1506 } 1507 TEST_F(WebRtcVideoMediaChannelTest, SetSendWithoutCodecs) { 1508 Base::SetSendWithoutCodecs(); 1509 } 1510 TEST_F(WebRtcVideoMediaChannelTest, SetSendSetsTransportBufferSizes) { 1511 Base::SetSendSetsTransportBufferSizes(); 1512 } 1513 1514 TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Vga) { 1515 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0)); 1516 } 1517 TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qvga) { 1518 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0)); 1519 } 1520 TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveH264SvcQqvga) { 1521 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0)); 1522 } 1523 TEST_F(WebRtcVideoMediaChannelTest, SendManyResizeOnce) { 1524 SendManyResizeOnce(); 1525 } 1526 1527 TEST_F(WebRtcVideoMediaChannelTest, SendVp8HdAndReceiveAdaptedVp8Vga) { 1528 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL)); 1529 channel_->UpdateAspectRatio(1280, 720); 1530 video_capturer_.reset(new cricket::FakeVideoCapturer); 1531 const std::vector<cricket::VideoFormat>* formats = 1532 video_capturer_->GetSupportedFormats(); 1533 cricket::VideoFormat capture_format_hd = (*formats)[0]; 1534 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd)); 1535 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get())); 1536 1537 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA. 1538 cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0); 1539 EXPECT_TRUE(SetOneCodec(codec)); 1540 codec.width /= 2; 1541 codec.height /= 2; 1542 EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, cricket::VideoFormat( 1543 codec.width, codec.height, 1544 cricket::VideoFormat::FpsToInterval(codec.framerate), 1545 cricket::FOURCC_ANY))); 1546 EXPECT_TRUE(SetSend(true)); 1547 EXPECT_TRUE(channel_->SetRender(true)); 1548 EXPECT_EQ(0, renderer_.num_rendered_frames()); 1549 EXPECT_TRUE(SendFrame()); 1550 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); 1551 } 1552 1553 // TODO(juberti): Fix this test to tolerate missing stats. 1554 TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStats) { 1555 Base::GetStats(); 1556 } 1557 1558 // TODO(juberti): Fix this test to tolerate missing stats. 1559 TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStatsMultipleRecvStreams) { 1560 Base::GetStatsMultipleRecvStreams(); 1561 } 1562 1563 TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleSendStreams) { 1564 Base::GetStatsMultipleSendStreams(); 1565 } 1566 1567 TEST_F(WebRtcVideoMediaChannelTest, SetSendBandwidth) { 1568 Base::SetSendBandwidth(); 1569 } 1570 TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrc) { 1571 Base::SetSendSsrc(); 1572 } 1573 TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrcAfterSetCodecs) { 1574 Base::SetSendSsrcAfterSetCodecs(); 1575 } 1576 1577 TEST_F(WebRtcVideoMediaChannelTest, SetRenderer) { 1578 Base::SetRenderer(); 1579 } 1580 1581 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreams) { 1582 Base::AddRemoveRecvStreams(); 1583 } 1584 1585 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamAndRender) { 1586 Base::AddRemoveRecvStreamAndRender(); 1587 } 1588 1589 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamsNoConference) { 1590 Base::AddRemoveRecvStreamsNoConference(); 1591 } 1592 1593 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveSendStreams) { 1594 Base::AddRemoveSendStreams(); 1595 } 1596 1597 TEST_F(WebRtcVideoMediaChannelTest, SimulateConference) { 1598 Base::SimulateConference(); 1599 } 1600 1601 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturer) { 1602 Base::AddRemoveCapturer(); 1603 } 1604 1605 TEST_F(WebRtcVideoMediaChannelTest, RemoveCapturerWithoutAdd) { 1606 Base::RemoveCapturerWithoutAdd(); 1607 } 1608 1609 TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturerMultipleSources) { 1610 Base::AddRemoveCapturerMultipleSources(); 1611 } 1612 1613 // This test verifies DSCP settings are properly applied on video media channel. 1614 TEST_F(WebRtcVideoMediaChannelTest, TestSetDscpOptions) { 1615 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface( 1616 new cricket::FakeNetworkInterface); 1617 channel_->SetInterface(network_interface.get()); 1618 cricket::VideoOptions options; 1619 options.dscp.Set(true); 1620 EXPECT_TRUE(channel_->SetOptions(options)); 1621 EXPECT_EQ(talk_base::DSCP_AF41, network_interface->dscp()); 1622 options.dscp.Set(false); 1623 EXPECT_TRUE(channel_->SetOptions(options)); 1624 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp()); 1625 channel_->SetInterface(NULL); 1626 } 1627 1628 1629 TEST_F(WebRtcVideoMediaChannelTest, SetOptionsSucceedsWhenSending) { 1630 cricket::VideoOptions options; 1631 options.conference_mode.Set(true); 1632 EXPECT_TRUE(channel_->SetOptions(options)); 1633 1634 // Verify SetOptions returns true on a different options. 1635 cricket::VideoOptions options2; 1636 options2.adapt_input_to_cpu_usage.Set(true); 1637 EXPECT_TRUE(channel_->SetOptions(options2)); 1638 1639 // Set send codecs on the channel and start sending. 1640 std::vector<cricket::VideoCodec> codecs; 1641 codecs.push_back(kVP8Codec); 1642 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1643 EXPECT_TRUE(channel_->SetSend(true)); 1644 1645 // Verify SetOptions returns true if channel is already sending. 1646 cricket::VideoOptions options3; 1647 options3.conference_mode.Set(true); 1648 EXPECT_TRUE(channel_->SetOptions(options3)); 1649 } 1650 1651 // Tests empty StreamParams is rejected. 1652 TEST_F(WebRtcVideoMediaChannelTest, RejectEmptyStreamParams) { 1653 Base::RejectEmptyStreamParams(); 1654 } 1655 1656 1657 TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution16x10) { 1658 Base::AdaptResolution16x10(); 1659 } 1660 1661 TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution4x3) { 1662 Base::AdaptResolution4x3(); 1663 } 1664 1665 TEST_F(WebRtcVideoMediaChannelTest, MuteStream) { 1666 Base::MuteStream(); 1667 } 1668 1669 TEST_F(WebRtcVideoMediaChannelTest, MultipleSendStreams) { 1670 Base::MultipleSendStreams(); 1671 } 1672 1673 // TODO(juberti): Restore this test once we support sending 0 fps. 1674 TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptDropAllFrames) { 1675 Base::AdaptDropAllFrames(); 1676 } 1677 // TODO(juberti): Understand why we get decode errors on this test. 1678 TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptFramerate) { 1679 Base::AdaptFramerate(); 1680 } 1681 1682 TEST_F(WebRtcVideoMediaChannelTest, SetSendStreamFormat0x0) { 1683 Base::SetSendStreamFormat0x0(); 1684 } 1685 1686 // TODO(zhurunz): Fix the flakey test. 1687 TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SetSendStreamFormat) { 1688 Base::SetSendStreamFormat(); 1689 } 1690 1691 TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsSendAndReceive) { 1692 Base::TwoStreamsSendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 1693 0)); 1694 } 1695 1696 TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsReUseFirstStream) { 1697 Base::TwoStreamsReUseFirstStream(cricket::VideoCodec(100, "VP8", 640, 400, 30, 1698 0)); 1699 } 1700 1701 TEST_F(WebRtcVideoEngineTestFake, ResetCodecOnScreencast) { 1702 EXPECT_TRUE(SetupEngine()); 1703 cricket::VideoOptions options; 1704 options.video_noise_reduction.Set(true); 1705 EXPECT_TRUE(channel_->SetOptions(options)); 1706 1707 // Set send codec. 1708 cricket::VideoCodec codec(kVP8Codec); 1709 std::vector<cricket::VideoCodec> codec_list; 1710 codec_list.push_back(codec); 1711 EXPECT_TRUE(channel_->AddSendStream( 1712 cricket::StreamParams::CreateLegacy(123))); 1713 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 1714 EXPECT_TRUE(channel_->SetSend(true)); 1715 EXPECT_EQ(1, vie_.num_set_send_codecs()); 1716 1717 webrtc::VideoCodec gcodec; 1718 memset(&gcodec, 0, sizeof(gcodec)); 1719 int channel_num = vie_.GetLastChannel(); 1720 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 1721 EXPECT_TRUE(gcodec.codecSpecific.VP8.denoisingOn); 1722 1723 // Send a screencast frame with the same size. 1724 // Verify that denoising is turned off. 1725 SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height); 1726 EXPECT_EQ(2, vie_.num_set_send_codecs()); 1727 EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); 1728 EXPECT_FALSE(gcodec.codecSpecific.VP8.denoisingOn); 1729 } 1730 1731 1732 TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderIfFactoryIsNotGiven) { 1733 engine_.SetExternalDecoderFactory(NULL); 1734 EXPECT_TRUE(SetupEngine()); 1735 int channel_num = vie_.GetLastChannel(); 1736 1737 std::vector<cricket::VideoCodec> codecs; 1738 codecs.push_back(kVP8Codec); 1739 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1740 1741 EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num)); 1742 } 1743 1744 TEST_F(WebRtcVideoEngineTestFake, RegisterDecoderIfFactoryIsGiven) { 1745 decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); 1746 engine_.SetExternalDecoderFactory(&decoder_factory_); 1747 EXPECT_TRUE(SetupEngine()); 1748 int channel_num = vie_.GetLastChannel(); 1749 1750 std::vector<cricket::VideoCodec> codecs; 1751 codecs.push_back(kVP8Codec); 1752 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1753 1754 EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100)); 1755 EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); 1756 } 1757 1758 TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderMultipleTimes) { 1759 decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); 1760 engine_.SetExternalDecoderFactory(&decoder_factory_); 1761 EXPECT_TRUE(SetupEngine()); 1762 int channel_num = vie_.GetLastChannel(); 1763 1764 std::vector<cricket::VideoCodec> codecs; 1765 codecs.push_back(kVP8Codec); 1766 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1767 1768 EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100)); 1769 EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); 1770 EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders()); 1771 1772 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1773 EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); 1774 EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders()); 1775 } 1776 1777 TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderForNonVP8) { 1778 decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); 1779 engine_.SetExternalDecoderFactory(&decoder_factory_); 1780 EXPECT_TRUE(SetupEngine()); 1781 int channel_num = vie_.GetLastChannel(); 1782 1783 std::vector<cricket::VideoCodec> codecs; 1784 codecs.push_back(kRedCodec); 1785 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1786 1787 EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num)); 1788 } 1789 1790 TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderIfFactoryIsNotGiven) { 1791 engine_.SetExternalEncoderFactory(NULL); 1792 EXPECT_TRUE(SetupEngine()); 1793 int channel_num = vie_.GetLastChannel(); 1794 1795 std::vector<cricket::VideoCodec> codecs; 1796 codecs.push_back(kVP8Codec); 1797 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1798 1799 EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num)); 1800 } 1801 1802 TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderIfFactoryIsGiven) { 1803 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 1804 engine_.SetExternalEncoderFactory(&encoder_factory_); 1805 EXPECT_TRUE(SetupEngine()); 1806 int channel_num = vie_.GetLastChannel(); 1807 1808 std::vector<cricket::VideoCodec> codecs; 1809 codecs.push_back(kVP8Codec); 1810 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1811 1812 EXPECT_TRUE(channel_->AddSendStream( 1813 cricket::StreamParams::CreateLegacy(kSsrc))); 1814 1815 EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); 1816 EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); 1817 1818 // Remove stream previously added to free the external encoder instance. 1819 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc)); 1820 } 1821 1822 TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderMultipleTimes) { 1823 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 1824 engine_.SetExternalEncoderFactory(&encoder_factory_); 1825 EXPECT_TRUE(SetupEngine()); 1826 int channel_num = vie_.GetLastChannel(); 1827 1828 std::vector<cricket::VideoCodec> codecs; 1829 codecs.push_back(kVP8Codec); 1830 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1831 1832 EXPECT_TRUE(channel_->AddSendStream( 1833 cricket::StreamParams::CreateLegacy(kSsrc))); 1834 1835 EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); 1836 EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); 1837 EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); 1838 1839 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1840 EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); 1841 EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); 1842 1843 // Remove stream previously added to free the external encoder instance. 1844 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc)); 1845 } 1846 1847 TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderWithMultipleSendStreams) { 1848 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 1849 engine_.SetExternalEncoderFactory(&encoder_factory_); 1850 EXPECT_TRUE(SetupEngine()); 1851 1852 std::vector<cricket::VideoCodec> codecs; 1853 codecs.push_back(kVP8Codec); 1854 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1855 EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); 1856 1857 // When we add the first stream (1234), it reuses the default send channel, 1858 // so it doesn't increase the registration count of external encoders. 1859 EXPECT_TRUE(channel_->AddSendStream( 1860 cricket::StreamParams::CreateLegacy(1234))); 1861 EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); 1862 1863 // When we add the second stream (2345), it creates a new channel and 1864 // increments the registration count. 1865 EXPECT_TRUE(channel_->AddSendStream( 1866 cricket::StreamParams::CreateLegacy(2345))); 1867 EXPECT_EQ(2, vie_.GetTotalNumExternalEncoderRegistered()); 1868 1869 // At this moment the total registration count is two, but only one encoder 1870 // is registered per channel. 1871 int channel_num = vie_.GetLastChannel(); 1872 EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); 1873 1874 // Removing send streams decrements the registration count. 1875 EXPECT_TRUE(channel_->RemoveSendStream(1234)); 1876 EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); 1877 1878 // When we remove the last send stream, it also destroys the last send 1879 // channel and causes the registration count to drop to zero. It is a little 1880 // weird, but not a bug. 1881 EXPECT_TRUE(channel_->RemoveSendStream(2345)); 1882 EXPECT_EQ(0, vie_.GetTotalNumExternalEncoderRegistered()); 1883 } 1884 1885 TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderForNonVP8) { 1886 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, 1887 "GENERIC"); 1888 engine_.SetExternalEncoderFactory(&encoder_factory_); 1889 EXPECT_TRUE(SetupEngine()); 1890 int channel_num = vie_.GetLastChannel(); 1891 1892 // Note: unlike the SetRecvCodecs, we must set a valid video codec for 1893 // channel_->SetSendCodecs() to succeed. 1894 std::vector<cricket::VideoCodec> codecs; 1895 codecs.push_back(kVP8Codec); 1896 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1897 1898 EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num)); 1899 } 1900 1901 // Test that NACK and REMB are enabled for external codec. 1902 TEST_F(WebRtcVideoEngineTestFake, FeedbackParamsForNonVP8) { 1903 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, 1904 "GENERIC"); 1905 engine_.SetExternalEncoderFactory(&encoder_factory_); 1906 encoder_factory_.NotifyCodecsAvailable(); 1907 EXPECT_TRUE(SetupEngine()); 1908 1909 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 1910 // The external codec will appear at last. 1911 size_t pos = codecs.size() - 1; 1912 EXPECT_EQ("GENERIC", codecs[pos].name); 1913 EXPECT_TRUE(codecs[pos].HasFeedbackParam( 1914 cricket::FeedbackParam(cricket::kRtcpFbParamNack, 1915 cricket::kParamValueEmpty))); 1916 EXPECT_TRUE(codecs[pos].HasFeedbackParam( 1917 cricket::FeedbackParam(cricket::kRtcpFbParamRemb, 1918 cricket::kParamValueEmpty))); 1919 EXPECT_TRUE(codecs[pos].HasFeedbackParam( 1920 cricket::FeedbackParam(cricket::kRtcpFbParamCcm, 1921 cricket::kRtcpFbCcmParamFir))); 1922 } 1923 1924 // Test external codec with be added to the end of the supported codec list. 1925 TEST_F(WebRtcVideoEngineTestFake, ExternalCodecAddedToTheEnd) { 1926 EXPECT_TRUE(SetupEngine()); 1927 1928 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 1929 EXPECT_EQ("VP8", codecs[0].name); 1930 1931 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, 1932 "GENERIC"); 1933 engine_.SetExternalEncoderFactory(&encoder_factory_); 1934 encoder_factory_.NotifyCodecsAvailable(); 1935 1936 codecs = engine_.codecs(); 1937 cricket::VideoCodec internal_codec = codecs[0]; 1938 cricket::VideoCodec external_codec = codecs[codecs.size() - 1]; 1939 // The external codec will appear at last. 1940 EXPECT_EQ("GENERIC", external_codec.name); 1941 // The internal codec is preferred. 1942 EXPECT_GE(internal_codec.preference, external_codec.preference); 1943 } 1944 1945 // Test that external codec with be ignored if it has the same name as one of 1946 // the internal codecs. 1947 TEST_F(WebRtcVideoEngineTestFake, ExternalCodecIgnored) { 1948 EXPECT_TRUE(SetupEngine()); 1949 1950 std::vector<cricket::VideoCodec> internal_codecs(engine_.codecs()); 1951 EXPECT_EQ("VP8", internal_codecs[0].name); 1952 1953 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 1954 engine_.SetExternalEncoderFactory(&encoder_factory_); 1955 encoder_factory_.NotifyCodecsAvailable(); 1956 1957 std::vector<cricket::VideoCodec> codecs = engine_.codecs(); 1958 EXPECT_EQ("VP8", codecs[0].name); 1959 EXPECT_EQ(internal_codecs[0].height, codecs[0].height); 1960 EXPECT_EQ(internal_codecs[0].width, codecs[0].width); 1961 // Verify the last codec is not the external codec. 1962 EXPECT_NE("VP8", codecs[codecs.size() - 1].name); 1963 } 1964 1965 TEST_F(WebRtcVideoEngineTestFake, UpdateEncoderCodecsAfterSetFactory) { 1966 engine_.SetExternalEncoderFactory(&encoder_factory_); 1967 EXPECT_TRUE(SetupEngine()); 1968 int channel_num = vie_.GetLastChannel(); 1969 1970 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 1971 encoder_factory_.NotifyCodecsAvailable(); 1972 std::vector<cricket::VideoCodec> codecs; 1973 codecs.push_back(kVP8Codec); 1974 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1975 1976 EXPECT_TRUE(channel_->AddSendStream( 1977 cricket::StreamParams::CreateLegacy(kSsrc))); 1978 1979 EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); 1980 EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); 1981 EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); 1982 1983 // Remove stream previously added to free the external encoder instance. 1984 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc)); 1985 } 1986 1987 // Tests that OnReadyToSend will be propagated into ViE. 1988 TEST_F(WebRtcVideoEngineTestFake, OnReadyToSend) { 1989 EXPECT_TRUE(SetupEngine()); 1990 int channel_num = vie_.GetLastChannel(); 1991 EXPECT_TRUE(vie_.GetIsTransmitting(channel_num)); 1992 1993 channel_->OnReadyToSend(false); 1994 EXPECT_FALSE(vie_.GetIsTransmitting(channel_num)); 1995 1996 channel_->OnReadyToSend(true); 1997 EXPECT_TRUE(vie_.GetIsTransmitting(channel_num)); 1998 } 1999 2000 #if 0 2001 TEST_F(WebRtcVideoEngineTestFake, CaptureFrameTimestampToNtpTimestamp) { 2002 EXPECT_TRUE(SetupEngine()); 2003 int capture_id = vie_.GetCaptureId(vie_.GetLastChannel()); 2004 2005 // Set send codec. 2006 cricket::VideoCodec codec(kVP8Codec); 2007 std::vector<cricket::VideoCodec> codec_list; 2008 codec_list.push_back(codec); 2009 EXPECT_TRUE(channel_->AddSendStream( 2010 cricket::StreamParams::CreateLegacy(123))); 2011 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 2012 EXPECT_TRUE(channel_->SetSend(true)); 2013 2014 int64 timestamp = time(NULL) * talk_base::kNumNanosecsPerSec; 2015 SendI420ScreencastFrameWithTimestamp( 2016 kVP8Codec.width, kVP8Codec.height, timestamp); 2017 EXPECT_EQ(talk_base::UnixTimestampNanosecsToNtpMillisecs(timestamp), 2018 vie_.GetCaptureLastTimestamp(capture_id)); 2019 2020 SendI420ScreencastFrameWithTimestamp(kVP8Codec.width, kVP8Codec.height, 0); 2021 EXPECT_EQ(0, vie_.GetCaptureLastTimestamp(capture_id)); 2022 } 2023 #endif 2024