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 <map> 29 #include <vector> 30 31 #include "talk/base/gunit.h" 32 #include "talk/media/base/testutils.h" 33 #include "talk/media/base/videoengine_unittest.h" 34 #include "talk/media/webrtc/webrtcvideoengine2.h" 35 #include "talk/media/webrtc/webrtcvideoengine2_unittest.h" 36 #include "talk/media/webrtc/webrtcvideochannelfactory.h" 37 38 namespace { 39 static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0); 40 static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0); 41 static const cricket::VideoCodec kVp8Codec270p(100, "VP8", 480, 270, 30, 0); 42 static const cricket::VideoCodec kVp8Codec180p(100, "VP8", 320, 180, 30, 0); 43 44 static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0); 45 static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0); 46 static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0); 47 static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0); 48 49 static const uint32 kSsrcs1[] = {1}; 50 static const uint32 kRtxSsrcs1[] = {4}; 51 52 void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) { 53 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 54 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty))); 55 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 56 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli))); 57 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 58 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty))); 59 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 60 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir))); 61 } 62 63 } // namespace 64 65 namespace cricket { 66 FakeVideoSendStream::FakeVideoSendStream( 67 const webrtc::VideoSendStream::Config& config, 68 const std::vector<webrtc::VideoStream>& video_streams) 69 : sending_(false), config_(config), video_streams_(video_streams) { 70 } 71 72 webrtc::VideoSendStream::Config FakeVideoSendStream::GetConfig() { 73 return config_; 74 } 75 76 std::vector<webrtc::VideoStream> FakeVideoSendStream::GetVideoStreams() { 77 return video_streams_; 78 } 79 80 bool FakeVideoSendStream::IsSending() { 81 return sending_; 82 } 83 84 webrtc::VideoSendStream::Stats FakeVideoSendStream::GetStats() const { 85 return webrtc::VideoSendStream::Stats(); 86 } 87 88 bool FakeVideoSendStream::ReconfigureVideoEncoder( 89 const std::vector<webrtc::VideoStream>& streams, 90 const void* encoder_specific) { 91 video_streams_ = streams; 92 return true; 93 } 94 95 webrtc::VideoSendStreamInput* FakeVideoSendStream::Input() { 96 // TODO(pbos): Fix. 97 return NULL; 98 } 99 100 void FakeVideoSendStream::Start() { 101 sending_ = true; 102 } 103 104 void FakeVideoSendStream::Stop() { 105 sending_ = false; 106 } 107 108 FakeVideoReceiveStream::FakeVideoReceiveStream( 109 const webrtc::VideoReceiveStream::Config& config) 110 : config_(config), receiving_(false) { 111 } 112 113 webrtc::VideoReceiveStream::Config FakeVideoReceiveStream::GetConfig() { 114 return config_; 115 } 116 117 webrtc::VideoReceiveStream::Stats FakeVideoReceiveStream::GetStats() const { 118 return webrtc::VideoReceiveStream::Stats(); 119 } 120 121 void FakeVideoReceiveStream::Start() { 122 receiving_ = true; 123 } 124 void FakeVideoReceiveStream::Stop() { 125 receiving_ = false; 126 } 127 void FakeVideoReceiveStream::GetCurrentReceiveCodec(webrtc::VideoCodec* codec) { 128 } 129 130 FakeCall::FakeCall() { SetVideoCodecs(GetDefaultVideoCodecs()); } 131 132 FakeCall::~FakeCall() { 133 EXPECT_EQ(0u, video_send_streams_.size()); 134 EXPECT_EQ(0u, video_receive_streams_.size()); 135 } 136 137 void FakeCall::SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs) { 138 codecs_ = codecs; 139 } 140 141 std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() { 142 return video_send_streams_; 143 } 144 145 std::vector<FakeVideoReceiveStream*> FakeCall::GetVideoReceiveStreams() { 146 return video_receive_streams_; 147 } 148 149 webrtc::VideoCodec FakeCall::GetEmptyVideoCodec() { 150 webrtc::VideoCodec codec; 151 codec.minBitrate = 300; 152 codec.startBitrate = 800; 153 codec.maxBitrate = 1500; 154 codec.maxFramerate = 10; 155 codec.width = 640; 156 codec.height = 480; 157 codec.qpMax = 56; 158 159 return codec; 160 } 161 162 webrtc::VideoCodec FakeCall::GetVideoCodecVp8() { 163 webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec(); 164 vp8_codec.codecType = webrtc::kVideoCodecVP8; 165 strcpy(vp8_codec.plName, kVp8Codec.name.c_str()); 166 vp8_codec.plType = kVp8Codec.id; 167 168 return vp8_codec; 169 } 170 171 webrtc::VideoCodec FakeCall::GetVideoCodecVp9() { 172 webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec(); 173 // TODO(pbos): Add a correct codecType when webrtc has one. 174 vp9_codec.codecType = webrtc::kVideoCodecVP8; 175 strcpy(vp9_codec.plName, kVp9Codec.name.c_str()); 176 vp9_codec.plType = kVp9Codec.id; 177 178 return vp9_codec; 179 } 180 181 std::vector<webrtc::VideoCodec> FakeCall::GetDefaultVideoCodecs() { 182 std::vector<webrtc::VideoCodec> codecs; 183 codecs.push_back(GetVideoCodecVp8()); 184 // codecs.push_back(GetVideoCodecVp9()); 185 186 return codecs; 187 } 188 189 webrtc::VideoSendStream::Config FakeCall::GetDefaultSendConfig() { 190 webrtc::VideoSendStream::Config config; 191 // TODO(pbos): Encoder settings. 192 // config.codec = GetVideoCodecVp8(); 193 return config; 194 } 195 196 webrtc::VideoSendStream* FakeCall::CreateVideoSendStream( 197 const webrtc::VideoSendStream::Config& config, 198 const std::vector<webrtc::VideoStream>& video_streams, 199 const void* encoder_settings) { 200 FakeVideoSendStream* fake_stream = 201 new FakeVideoSendStream(config, video_streams); 202 video_send_streams_.push_back(fake_stream); 203 return fake_stream; 204 } 205 206 void FakeCall::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) { 207 FakeVideoSendStream* fake_stream = 208 static_cast<FakeVideoSendStream*>(send_stream); 209 for (size_t i = 0; i < video_send_streams_.size(); ++i) { 210 if (video_send_streams_[i] == fake_stream) { 211 delete video_send_streams_[i]; 212 video_send_streams_.erase(video_send_streams_.begin() + i); 213 return; 214 } 215 } 216 ADD_FAILURE() << "DestroyVideoSendStream called with unknown paramter."; 217 } 218 219 webrtc::VideoReceiveStream::Config FakeCall::GetDefaultReceiveConfig() { 220 return webrtc::VideoReceiveStream::Config(); 221 } 222 223 webrtc::VideoReceiveStream* FakeCall::CreateVideoReceiveStream( 224 const webrtc::VideoReceiveStream::Config& config) { 225 video_receive_streams_.push_back(new FakeVideoReceiveStream(config)); 226 return video_receive_streams_[video_receive_streams_.size() - 1]; 227 } 228 229 void FakeCall::DestroyVideoReceiveStream( 230 webrtc::VideoReceiveStream* receive_stream) { 231 FakeVideoReceiveStream* fake_stream = 232 static_cast<FakeVideoReceiveStream*>(receive_stream); 233 for (size_t i = 0; i < video_receive_streams_.size(); ++i) { 234 if (video_receive_streams_[i] == fake_stream) { 235 delete video_receive_streams_[i]; 236 video_receive_streams_.erase(video_receive_streams_.begin() + i); 237 return; 238 } 239 } 240 ADD_FAILURE() << "DestroyVideoReceiveStream called with unknown paramter."; 241 } 242 243 webrtc::PacketReceiver* FakeCall::Receiver() { 244 // TODO(pbos): Fix this. 245 return NULL; 246 } 247 248 uint32_t FakeCall::SendBitrateEstimate() { 249 return 0; 250 } 251 252 uint32_t FakeCall::ReceiveBitrateEstimate() { 253 return 0; 254 } 255 256 FakeWebRtcVideoChannel2::FakeWebRtcVideoChannel2( 257 FakeCall* call, 258 WebRtcVideoEngine2* engine, 259 VoiceMediaChannel* voice_channel) 260 : WebRtcVideoChannel2(call, engine, engine->GetVideoEncoderFactory()), 261 fake_call_(call), 262 voice_channel_(voice_channel) { 263 } 264 265 FakeWebRtcVideoChannel2::~FakeWebRtcVideoChannel2() { 266 } 267 268 VoiceMediaChannel* FakeWebRtcVideoChannel2::GetVoiceChannel() { 269 return voice_channel_; 270 } 271 FakeCall* FakeWebRtcVideoChannel2::GetFakeCall() { 272 return fake_call_; 273 } 274 275 FakeWebRtcVideoChannel2* FakeWebRtcVideoMediaChannelFactory::GetFakeChannel( 276 VideoMediaChannel* channel) { 277 return channel_map_[channel]; 278 } 279 280 WebRtcVideoChannel2* FakeWebRtcVideoMediaChannelFactory::Create( 281 WebRtcVideoEngine2* engine, 282 VoiceMediaChannel* voice_channel) { 283 FakeWebRtcVideoChannel2* channel = 284 new FakeWebRtcVideoChannel2(new FakeCall(), engine, voice_channel); 285 channel_map_[channel] = channel; 286 return channel; 287 } 288 289 class WebRtcVideoEngine2Test : public testing::Test { 290 public: 291 WebRtcVideoEngine2Test() : engine_(&factory_) { 292 std::vector<VideoCodec> engine_codecs = engine_.codecs(); 293 assert(!engine_codecs.empty()); 294 bool codec_set = false; 295 for (size_t i = 0; i < engine_codecs.size(); ++i) { 296 if (engine_codecs[i].name == "red") { 297 default_red_codec_ = engine_codecs[i]; 298 } else if (engine_codecs[i].name == "ulpfec") { 299 default_ulpfec_codec_ = engine_codecs[i]; 300 } else if (engine_codecs[i].name == "rtx") { 301 default_rtx_codec_ = engine_codecs[i]; 302 } else if (!codec_set) { 303 default_codec_ = engine_codecs[i]; 304 codec_set = true; 305 } 306 } 307 308 assert(codec_set); 309 } 310 311 protected: 312 FakeWebRtcVideoMediaChannelFactory factory_; 313 WebRtcVideoEngine2 engine_; 314 VideoCodec default_codec_; 315 VideoCodec default_red_codec_; 316 VideoCodec default_ulpfec_codec_; 317 VideoCodec default_rtx_codec_; 318 }; 319 320 TEST_F(WebRtcVideoEngine2Test, CreateChannel) { 321 talk_base::scoped_ptr<VideoMediaChannel> channel(engine_.CreateChannel(NULL)); 322 ASSERT_TRUE(channel.get() != NULL) << "Could not create channel."; 323 EXPECT_TRUE(factory_.GetFakeChannel(channel.get()) != NULL) 324 << "Channel not created through factory."; 325 } 326 327 TEST_F(WebRtcVideoEngine2Test, CreateChannelWithVoiceEngine) { 328 VoiceMediaChannel* voice_channel = reinterpret_cast<VoiceMediaChannel*>(0x42); 329 talk_base::scoped_ptr<VideoMediaChannel> channel( 330 engine_.CreateChannel(voice_channel)); 331 ASSERT_TRUE(channel.get() != NULL) << "Could not create channel."; 332 333 FakeWebRtcVideoChannel2* fake_channel = 334 factory_.GetFakeChannel(channel.get()); 335 ASSERT_TRUE(fake_channel != NULL) << "Channel not created through factory."; 336 337 EXPECT_TRUE(fake_channel->GetVoiceChannel() != NULL) 338 << "VoiceChannel not set."; 339 EXPECT_EQ(voice_channel, fake_channel->GetVoiceChannel()) 340 << "Different VoiceChannel set than the provided one."; 341 } 342 343 TEST_F(WebRtcVideoEngine2Test, FindCodec) { 344 const std::vector<cricket::VideoCodec>& c = engine_.codecs(); 345 EXPECT_EQ(4U, c.size()); 346 347 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); 348 EXPECT_TRUE(engine_.FindCodec(vp8)); 349 350 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0); 351 EXPECT_TRUE(engine_.FindCodec(vp8)); 352 353 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50); 354 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref)); 355 356 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0); 357 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id)); 358 vp8_diff_id.id = 97; 359 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id)); 360 361 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0); 362 EXPECT_FALSE(engine_.FindCodec(vp8_diff_res)); 363 364 // PeerConnection doesn't negotiate the resolution at this point. 365 // Test that FindCodec can handle the case when width/height is 0. 366 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0); 367 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res)); 368 369 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0); 370 EXPECT_TRUE(engine_.FindCodec(red)); 371 372 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0); 373 EXPECT_TRUE(engine_.FindCodec(red)); 374 375 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0); 376 EXPECT_TRUE(engine_.FindCodec(fec)); 377 378 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0); 379 EXPECT_TRUE(engine_.FindCodec(fec)); 380 381 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0); 382 EXPECT_TRUE(engine_.FindCodec(rtx)); 383 } 384 385 TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) { 386 std::vector<VideoCodec> engine_codecs = engine_.codecs(); 387 for (size_t i = 0; i < engine_codecs.size(); ++i) { 388 if (engine_codecs[i].name != kRtxCodecName) 389 continue; 390 int associated_payload_type; 391 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType, 392 &associated_payload_type)); 393 EXPECT_EQ(default_codec_.id, associated_payload_type); 394 return; 395 } 396 FAIL() << "No RTX codec found among default codecs."; 397 } 398 399 TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) { 400 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions(); 401 ASSERT_FALSE(extensions.empty()); 402 for (size_t i = 0; i < extensions.size(); ++i) { 403 if (extensions[i].uri == kRtpTimestampOffsetHeaderExtension) { 404 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extensions[i].id); 405 return; 406 } 407 } 408 FAIL() << "Timestamp offset extension not in header-extension list."; 409 } 410 411 TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) { 412 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions(); 413 ASSERT_FALSE(extensions.empty()); 414 for (size_t i = 0; i < extensions.size(); ++i) { 415 if (extensions[i].uri == kRtpAbsoluteSenderTimeHeaderExtension) { 416 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId, 417 extensions[i].id); 418 return; 419 } 420 } 421 FAIL() << "Absolute Sender Time extension not in header-extension list."; 422 } 423 424 class WebRtcVideoChannel2BaseTest 425 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> { 426 protected: 427 virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; } 428 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base; 429 }; 430 431 // TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize. 432 #if 0 433 // TODO(juberti): Figure out why ViE is munging the COM refcount. 434 #ifdef WIN32 435 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_CheckCoInitialize) { 436 Base::CheckCoInitialize(); 437 } 438 #endif 439 #endif 440 441 TEST_F(WebRtcVideoChannel2BaseTest, SetSend) { Base::SetSend(); } 442 443 TEST_F(WebRtcVideoChannel2BaseTest, SetSendWithoutCodecs) { 444 Base::SetSendWithoutCodecs(); 445 } 446 447 TEST_F(WebRtcVideoChannel2BaseTest, SetSendSetsTransportBufferSizes) { 448 Base::SetSendSetsTransportBufferSizes(); 449 } 450 451 // TODO(juberti): Fix this test to tolerate missing stats. 452 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStats) { Base::GetStats(); } 453 454 // TODO(juberti): Fix this test to tolerate missing stats. 455 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleRecvStreams) { 456 Base::GetStatsMultipleRecvStreams(); 457 } 458 459 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleSendStreams) { 460 Base::GetStatsMultipleSendStreams(); 461 } 462 463 TEST_F(WebRtcVideoChannel2BaseTest, SetSendBandwidth) { 464 Base::SetSendBandwidth(); 465 } 466 TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrc) { Base::SetSendSsrc(); } 467 TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrcAfterSetCodecs) { 468 Base::SetSendSsrcAfterSetCodecs(); 469 } 470 471 TEST_F(WebRtcVideoChannel2BaseTest, SetRenderer) { Base::SetRenderer(); } 472 473 TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreams) { 474 Base::AddRemoveRecvStreams(); 475 } 476 477 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AddRemoveRecvStreamAndRender) { 478 Base::AddRemoveRecvStreamAndRender(); 479 } 480 481 TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreamsNoConference) { 482 Base::AddRemoveRecvStreamsNoConference(); 483 } 484 485 TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveSendStreams) { 486 Base::AddRemoveSendStreams(); 487 } 488 489 TEST_F(WebRtcVideoChannel2BaseTest, SimulateConference) { 490 Base::SimulateConference(); 491 } 492 493 TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturer) { 494 Base::AddRemoveCapturer(); 495 } 496 497 TEST_F(WebRtcVideoChannel2BaseTest, RemoveCapturerWithoutAdd) { 498 Base::RemoveCapturerWithoutAdd(); 499 } 500 501 TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturerMultipleSources) { 502 Base::AddRemoveCapturerMultipleSources(); 503 } 504 505 // TODO(pbos): Figure out why this fails so often. 506 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_HighAspectHighHeightCapturer) { 507 Base::HighAspectHighHeightCapturer(); 508 } 509 510 TEST_F(WebRtcVideoChannel2BaseTest, RejectEmptyStreamParams) { 511 Base::RejectEmptyStreamParams(); 512 } 513 514 TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution16x10) { 515 Base::AdaptResolution16x10(); 516 } 517 518 TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution4x3) { 519 Base::AdaptResolution4x3(); 520 } 521 522 TEST_F(WebRtcVideoChannel2BaseTest, MuteStream) { Base::MuteStream(); } 523 524 TEST_F(WebRtcVideoChannel2BaseTest, MultipleSendStreams) { 525 Base::MultipleSendStreams(); 526 } 527 528 // TODO(juberti): Restore this test once we support sending 0 fps. 529 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptDropAllFrames) { 530 Base::AdaptDropAllFrames(); 531 } 532 // TODO(juberti): Understand why we get decode errors on this test. 533 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptFramerate) { 534 Base::AdaptFramerate(); 535 } 536 537 TEST_F(WebRtcVideoChannel2BaseTest, SetSendStreamFormat0x0) { 538 Base::SetSendStreamFormat0x0(); 539 } 540 541 // TODO(zhurunz): Fix the flakey test. 542 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SetSendStreamFormat) { 543 Base::SetSendStreamFormat(); 544 } 545 546 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) { 547 Base::TwoStreamsSendAndReceive(kVp8Codec); 548 } 549 550 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) { 551 Base::TwoStreamsReUseFirstStream(kVp8Codec); 552 } 553 554 class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { 555 public: 556 virtual void SetUp() OVERRIDE { 557 channel_.reset(engine_.CreateChannel(NULL)); 558 fake_channel_ = factory_.GetFakeChannel(channel_.get()); 559 last_ssrc_ = 123; 560 ASSERT_TRUE(fake_channel_ != NULL) 561 << "Channel not created through factory."; 562 } 563 564 protected: 565 FakeVideoSendStream* AddSendStream() { 566 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++)); 567 } 568 569 FakeVideoSendStream* AddSendStream(const StreamParams& sp) { 570 size_t num_streams = 571 fake_channel_->GetFakeCall()->GetVideoSendStreams().size(); 572 EXPECT_TRUE(channel_->AddSendStream(sp)); 573 std::vector<FakeVideoSendStream*> streams = 574 fake_channel_->GetFakeCall()->GetVideoSendStreams(); 575 EXPECT_EQ(num_streams + 1, streams.size()); 576 return streams[streams.size() - 1]; 577 } 578 579 std::vector<FakeVideoSendStream*> GetFakeSendStreams() { 580 return fake_channel_->GetFakeCall()->GetVideoSendStreams(); 581 } 582 583 FakeVideoReceiveStream* AddRecvStream() { 584 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++)); 585 } 586 587 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) { 588 size_t num_streams = 589 fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size(); 590 EXPECT_TRUE(channel_->AddRecvStream(sp)); 591 std::vector<FakeVideoReceiveStream*> streams = 592 fake_channel_->GetFakeCall()->GetVideoReceiveStreams(); 593 EXPECT_EQ(num_streams + 1, streams.size()); 594 return streams[streams.size() - 1]; 595 } 596 597 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate, 598 const char* max_bitrate) { 599 std::vector<VideoCodec> codecs; 600 codecs.push_back(kVp8Codec); 601 codecs[0].params[kCodecParamMinBitrate] = min_bitrate; 602 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate; 603 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 604 605 FakeVideoSendStream* stream = AddSendStream(); 606 607 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams(); 608 ASSERT_EQ(1u, video_streams.size()); 609 EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000); 610 EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000); 611 612 VideoCodec codec; 613 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 614 EXPECT_EQ(min_bitrate, codec.params[kCodecParamMinBitrate]); 615 EXPECT_EQ(max_bitrate, codec.params[kCodecParamMaxBitrate]); 616 } 617 618 void ExpectEqualCodecs(const VideoCodec video_codec, 619 const webrtc::VideoCodec& webrtc_codec) { 620 EXPECT_STREQ(video_codec.name.c_str(), webrtc_codec.plName); 621 EXPECT_EQ(video_codec.id, webrtc_codec.plType); 622 EXPECT_EQ(video_codec.width, webrtc_codec.width); 623 EXPECT_EQ(video_codec.height, webrtc_codec.height); 624 EXPECT_EQ(video_codec.framerate, webrtc_codec.maxFramerate); 625 } 626 627 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext, 628 const std::string& webrtc_ext) { 629 // Enable extension. 630 const int id = 1; 631 std::vector<cricket::RtpHeaderExtension> extensions; 632 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id)); 633 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 634 635 FakeVideoSendStream* send_stream = 636 AddSendStream(cricket::StreamParams::CreateLegacy(123)); 637 638 // Verify the send extension id. 639 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size()); 640 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id); 641 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name); 642 // Verify call with same set of extensions returns true. 643 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); 644 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for 645 // receivers. 646 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123)) 647 ->GetConfig() 648 .rtp.extensions.empty()); 649 650 // Remove the extension id, verify that this doesn't reset extensions as 651 // they should be set before creating channels. 652 std::vector<cricket::RtpHeaderExtension> empty_extensions; 653 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); 654 EXPECT_FALSE(send_stream->GetConfig().rtp.extensions.empty()); 655 } 656 657 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext, 658 const std::string& webrtc_ext) { 659 // Enable extension. 660 const int id = 1; 661 std::vector<cricket::RtpHeaderExtension> extensions; 662 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id)); 663 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 664 665 FakeVideoReceiveStream* recv_stream = 666 AddRecvStream(cricket::StreamParams::CreateLegacy(123)); 667 668 // Verify the recv extension id. 669 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size()); 670 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id); 671 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name); 672 // Verify call with same set of extensions returns true. 673 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); 674 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for 675 // senders. 676 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123)) 677 ->GetConfig() 678 .rtp.extensions.empty()); 679 680 // Remove the extension id, verify that this doesn't reset extensions as 681 // they should be set before creating channels. 682 std::vector<cricket::RtpHeaderExtension> empty_extensions; 683 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); 684 EXPECT_FALSE(recv_stream->GetConfig().rtp.extensions.empty()); 685 } 686 687 talk_base::scoped_ptr<VideoMediaChannel> channel_; 688 FakeWebRtcVideoChannel2* fake_channel_; 689 uint32 last_ssrc_; 690 }; 691 692 TEST_F(WebRtcVideoChannel2Test, DISABLED_MaxBitrateResetsWithConferenceMode) { 693 FAIL() << "Not implemented."; // TODO(pbos): Implement. 694 } 695 696 TEST_F(WebRtcVideoChannel2Test, DISABLED_StartSendBitrate) { 697 // TODO(pbos): Is this test testing vie_ ? this is confusing. No API to set 698 // start send bitrate from outside? Add defaults here that should be kept? 699 std::vector<cricket::VideoCodec> codec_list; 700 codec_list.push_back(kVp8Codec); 701 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 702 const unsigned int kVideoMinSendBitrateKbps = 50; 703 const unsigned int kVideoTargetSendBitrateKbps = 300; 704 const unsigned int kVideoMaxSendBitrateKbps = 2000; 705 FakeVideoSendStream* stream = AddSendStream(); 706 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams(); 707 ASSERT_EQ(1u, video_streams.size()); 708 EXPECT_EQ(kVideoMinSendBitrateKbps, 709 video_streams.back().min_bitrate_bps / 1000); 710 EXPECT_EQ(kVideoTargetSendBitrateKbps, 711 video_streams.back().target_bitrate_bps / 1000); 712 EXPECT_EQ(kVideoMaxSendBitrateKbps, 713 video_streams.back().max_bitrate_bps / 1000); 714 #if 0 715 // TODO(pbos): un-#if 716 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 717 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 718 kVideoDefaultStartSendBitrateKbps); 719 EXPECT_EQ(0, vie_.StartSend(send_channel)); 720 721 // Increase the send bitrate and verify it is used as start bitrate. 722 const unsigned int kVideoSendBitrateBps = 768000; 723 vie_.SetSendBitrates(send_channel, kVideoSendBitrateBps, 0, 0); 724 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 725 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 726 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 727 kVideoSendBitrateBps / 1000); 728 729 // Never set a start bitrate higher than the max bitrate. 730 vie_.SetSendBitrates(send_channel, kVideoMaxSendBitrateKbps + 500, 0, 0); 731 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 732 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 733 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 734 kVideoDefaultStartSendBitrateKbps); 735 736 // Use the default start bitrate if the send bitrate is lower. 737 vie_.SetSendBitrates(send_channel, kVideoDefaultStartSendBitrateKbps - 50, 0, 738 0); 739 EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); 740 VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, 741 kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, 742 kVideoDefaultStartSendBitrateKbps); 743 #endif 744 } 745 746 TEST_F(WebRtcVideoChannel2Test, DISABLED_RtcpEnabled) { 747 // Note(pbos): This is a receiver-side setting, dumbo. 748 FAIL() << "Not implemented."; // TODO(pbos): Implement. 749 } 750 751 TEST_F(WebRtcVideoChannel2Test, DISABLED_KeyFrameRequestEnabled) { 752 FAIL() << "Not implemented."; // TODO(pbos): Implement. 753 } 754 755 TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) { 756 FakeVideoReceiveStream* stream = AddRecvStream(); 757 EXPECT_TRUE(stream->GetConfig().rtp.remb); 758 } 759 760 TEST_F(WebRtcVideoChannel2Test, DISABLED_RembEnabledOnReceiveChannels) { 761 FAIL() << "Not implemented."; // TODO(pbos): Implement. 762 } 763 764 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) { 765 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 766 EXPECT_TRUE(channel_->SetSend(true)); 767 cricket::VideoOptions options; 768 options.conference_mode.Set(true); 769 EXPECT_TRUE(channel_->SetOptions(options)); 770 771 // Send side. 772 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1); 773 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 774 FakeVideoSendStream* send_stream = AddSendStream( 775 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 776 777 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size()); 778 for (size_t i = 0; i < rtx_ssrcs.size(); ++i) 779 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]); 780 781 // Receiver side. 782 FakeVideoReceiveStream* recv_stream = AddRecvStream( 783 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 784 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u) 785 << "No SSRCs for RTX configured by AddRecvStream."; 786 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()) 787 << "This test only works with one receive codec. Please update the test."; 788 EXPECT_EQ(rtx_ssrcs[0], 789 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); 790 // TODO(pbos): Make sure we set the RTX for correct payloads etc. 791 } 792 793 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) { 794 // Setup one channel with an associated RTX stream. 795 cricket::StreamParams params = 796 cricket::StreamParams::CreateLegacy(kSsrcs1[0]); 797 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]); 798 FakeVideoReceiveStream* recv_stream = AddRecvStream(params); 799 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()); 800 EXPECT_EQ(kRtxSsrcs1[0], 801 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); 802 } 803 804 TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) { 805 // Setup one channel without an associated RTX stream. 806 cricket::StreamParams params = 807 cricket::StreamParams::CreateLegacy(kSsrcs1[0]); 808 FakeVideoReceiveStream* recv_stream = AddRecvStream(params); 809 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty()); 810 } 811 812 TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) { 813 FakeVideoSendStream* send_stream = 814 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0])); 815 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty()); 816 817 FakeVideoReceiveStream* recv_stream = 818 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0])); 819 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty()); 820 } 821 822 // Test support for RTP timestamp offset header extension. 823 TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) { 824 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension, 825 webrtc::RtpExtension::kTOffset); 826 } 827 TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) { 828 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension, 829 webrtc::RtpExtension::kTOffset); 830 } 831 832 // Test support for absolute send time header extension. 833 TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) { 834 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension, 835 webrtc::RtpExtension::kAbsSendTime); 836 } 837 TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) { 838 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension, 839 webrtc::RtpExtension::kAbsSendTime); 840 } 841 842 TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) { 843 FAIL() << "Not implemented."; // TODO(pbos): Implement. 844 } 845 846 TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) { 847 FAIL() << "Not implemented."; // TODO(pbos): Implement. 848 } 849 850 TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) { 851 FAIL() << "Not implemented."; // TODO(pbos): Implement. 852 } 853 854 TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) { 855 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 856 EXPECT_EQ(1u, fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size()); 857 } 858 859 TEST_F(WebRtcVideoChannel2Test, DISABLED_NoRembChangeAfterAddRecvStream) { 860 FAIL() << "Not implemented."; // TODO(pbos): Implement. 861 } 862 863 TEST_F(WebRtcVideoChannel2Test, DISABLED_RembOnOff) { 864 FAIL() << "Not implemented."; // TODO(pbos): Implement. 865 } 866 867 TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) { 868 VerifyCodecHasDefaultFeedbackParams(default_codec_); 869 870 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 871 EXPECT_TRUE(channel_->SetSend(true)); 872 873 // Send side. 874 FakeVideoSendStream* send_stream = 875 AddSendStream(cricket::StreamParams::CreateLegacy(1)); 876 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 877 878 // Receiver side. 879 FakeVideoReceiveStream* recv_stream = 880 AddRecvStream(cricket::StreamParams::CreateLegacy(1)); 881 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 882 883 // Nack history size should match between sender and receiver. 884 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms, 885 recv_stream->GetConfig().rtp.nack.rtp_history_ms); 886 } 887 888 TEST_F(WebRtcVideoChannel2Test, NackCanBeDisabled) { 889 std::vector<VideoCodec> codecs; 890 codecs.push_back(kVp8Codec); 891 892 // Send side. 893 ASSERT_TRUE(channel_->SetSendCodecs(codecs)); 894 FakeVideoSendStream* send_stream = 895 AddSendStream(cricket::StreamParams::CreateLegacy(1)); 896 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms); 897 898 // Receiver side. 899 ASSERT_TRUE(channel_->SetRecvCodecs(codecs)); 900 FakeVideoReceiveStream* recv_stream = 901 AddRecvStream(cricket::StreamParams::CreateLegacy(1)); 902 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms); 903 } 904 905 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) { 906 FAIL() << "Not implemented."; // TODO(pbos): Implement. 907 } 908 909 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) { 910 FAIL() << "Not implemented."; // TODO(pbos): Implement. 911 } 912 913 TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) { 914 FAIL() << "Not implemented."; // TODO(pbos): Implement. 915 } 916 917 TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) { 918 FAIL() << "Not implemented."; // TODO(pbos): Implement. 919 } 920 921 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) { 922 FAIL() << "Not implemented."; // TODO(pbos): Implement. 923 } 924 925 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) { 926 FAIL() << "Not implemented."; // TODO(pbos): Implement. 927 } 928 929 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) { 930 FAIL() << "Not implemented."; // TODO(pbos): Implement. 931 } 932 933 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) { 934 FAIL() << "Not implemented."; // TODO(pbos): Implement. 935 } 936 937 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) { 938 FAIL() << "Not implemented."; // TODO(pbos): Implement. 939 } 940 941 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthScreencast) { 942 FAIL() << "Not implemented."; // TODO(pbos): Implement. 943 } 944 945 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) { 946 FAIL() << "Not implemented."; // TODO(pbos): Implement. 947 } 948 949 TEST_F(WebRtcVideoChannel2Test, 950 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) { 951 FAIL() << "Not implemented."; // TODO(pbos): Implement. 952 } 953 954 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithDenoising) { 955 FAIL() << "Not implemented."; // TODO(pbos): Implement. 956 } 957 958 TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) { 959 FAIL() << "Not implemented."; // TODO(pbos): Implement. 960 } 961 962 TEST_F(WebRtcVideoChannel2Test, DISABLED_DISABLED_SendReceiveBitratesStats) { 963 FAIL() << "Not implemented."; // TODO(pbos): Implement. 964 } 965 966 TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetAdaptInputToCpuUsage) { 967 FAIL() << "Not implemented."; // TODO(pbos): Implement. 968 } 969 970 TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetCpuThreshold) { 971 FAIL() << "Not implemented."; // TODO(pbos): Implement. 972 } 973 974 TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetInvalidCpuThreshold) { 975 FAIL() << "Not implemented."; // TODO(pbos): Implement. 976 } 977 978 TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) { 979 FAIL() << "Not implemented."; // TODO(pbos): Implement. 980 } 981 982 TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldNotLog) { 983 FAIL() << "Not implemented."; // TODO(pbos): Implement. 984 } 985 986 TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { 987 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs())); 988 989 VideoCodec codec; 990 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 991 EXPECT_TRUE(codec.Matches(engine_.codecs()[0])); 992 993 // Using a RTX setup to verify that the default RTX payload type is good. 994 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1); 995 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 996 FakeVideoSendStream* stream = AddSendStream( 997 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 998 webrtc::VideoSendStream::Config config = stream->GetConfig(); 999 // TODO(pbos): Replace ExpectEqualCodecs. 1000 // ExpectEqualCodecs(engine_.codecs()[0], config.codec); 1001 1002 // Make sure NACK and FEC are enabled on the correct payload types. 1003 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms); 1004 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type); 1005 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type); 1006 // TODO(pbos): Verify that the rtx ssrc is set, correct, not taken by anything 1007 // else. 1008 // ASSERT_EQ(1u, config.rtp.rtx.ssrcs.size()); 1009 EXPECT_EQ(static_cast<int>(default_rtx_codec_.id), 1010 config.rtp.rtx.payload_type); 1011 // TODO(juberti): Check RTCP, PLI, TMMBR. 1012 } 1013 1014 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) { 1015 std::vector<VideoCodec> codecs; 1016 codecs.push_back(kVp8Codec); 1017 ASSERT_TRUE(channel_->SetSendCodecs(codecs)); 1018 1019 FakeVideoSendStream* stream = AddSendStream(); 1020 webrtc::VideoSendStream::Config config = stream->GetConfig(); 1021 1022 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type); 1023 EXPECT_EQ(-1, config.rtp.fec.red_payload_type); 1024 } 1025 1026 TEST_F(WebRtcVideoChannel2Test, 1027 DISABLED_SetSendCodecRejectsRtxWithoutAssociatedPayloadType) { 1028 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1029 } 1030 1031 TEST_F(WebRtcVideoChannel2Test, 1032 DISABLED_SetSendCodecRejectsRtxWithoutMatchingVideoCodec) { 1033 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1034 } 1035 1036 TEST_F(WebRtcVideoChannel2Test, 1037 DISABLED_SetCodecsWithoutFecDisablesCurrentFec) { 1038 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1039 } 1040 1041 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendCodecsChangesExistingStreams) { 1042 FAIL(); // TODO(pbos): Implement, make sure that it's changing running 1043 // streams. Should it? 1044 } 1045 1046 TEST_F(WebRtcVideoChannel2Test, 1047 DISABLED_ConstrainsSetCodecsAccordingToEncoderConfig) { 1048 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1049 } 1050 1051 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMinMaxBitrate) { 1052 SetSendCodecsShouldWorkForBitrates("10", "20"); 1053 } 1054 1055 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) { 1056 std::vector<VideoCodec> video_codecs = engine_.codecs(); 1057 video_codecs[0].params[kCodecParamMinBitrate] = "30"; 1058 video_codecs[0].params[kCodecParamMaxBitrate] = "20"; 1059 EXPECT_FALSE(channel_->SetSendCodecs(video_codecs)); 1060 } 1061 1062 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptLargeMinMaxBitrate) { 1063 SetSendCodecsShouldWorkForBitrates("1000", "2000"); 1064 } 1065 1066 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) { 1067 static const char* kMaxQuantization = "21"; 1068 std::vector<VideoCodec> codecs; 1069 codecs.push_back(kVp8Codec); 1070 codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization; 1071 EXPECT_TRUE(channel_->SetSendCodecs(codecs)); 1072 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)), 1073 AddSendStream()->GetVideoStreams().back().max_qp); 1074 1075 VideoCodec codec; 1076 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 1077 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]); 1078 } 1079 1080 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) { 1081 std::vector<cricket::VideoCodec> codecs; 1082 codecs.push_back(kVp8Codec); 1083 1084 codecs[0].width = 0; 1085 EXPECT_FALSE(channel_->SetSendCodecs(codecs)) 1086 << "Codec set though codec width is zero."; 1087 1088 codecs[0].width = kVp8Codec.width; 1089 codecs[0].height = 0; 1090 EXPECT_FALSE(channel_->SetSendCodecs(codecs)) 1091 << "Codec set though codec height is zero."; 1092 } 1093 1094 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { 1095 // TODO(pbos): Should we only allow the dynamic range? 1096 static const size_t kNumIncorrectPayloads = 4; 1097 static const int kIncorrectPayloads[kNumIncorrectPayloads] = {-2, -1, 128, 1098 129}; 1099 std::vector<cricket::VideoCodec> codecs; 1100 codecs.push_back(kVp8Codec); 1101 for (size_t i = 0; i < kNumIncorrectPayloads; ++i) { 1102 int payload_type = kIncorrectPayloads[i]; 1103 codecs[0].id = payload_type; 1104 EXPECT_FALSE(channel_->SetSendCodecs(codecs)) 1105 << "Bad payload type '" << payload_type << "' accepted."; 1106 } 1107 } 1108 1109 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) { 1110 std::vector<cricket::VideoCodec> codecs; 1111 codecs.push_back(kVp8Codec); 1112 for (int payload_type = 0; payload_type <= 127; ++payload_type) { 1113 codecs[0].id = payload_type; 1114 EXPECT_TRUE(channel_->SetSendCodecs(codecs)) 1115 << "Payload type '" << payload_type << "' rejected."; 1116 } 1117 } 1118 1119 TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetVieSendCodecOnNewFrameSize) { 1120 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1121 } 1122 1123 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) { 1124 std::vector<cricket::VideoCodec> codecs; 1125 codecs.push_back(kVp8Codec); 1126 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1127 } 1128 1129 // Test that we set our inbound RTX codecs properly. 1130 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) { 1131 std::vector<cricket::VideoCodec> codecs; 1132 codecs.push_back(kVp8Codec); 1133 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); 1134 codecs.push_back(rtx_codec); 1135 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) 1136 << "RTX codec without associated payload should be rejected."; 1137 1138 codecs[1].SetParam("apt", kVp8Codec.id + 1); 1139 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) 1140 << "RTX codec with invalid associated payload type should be rejected."; 1141 1142 codecs[1].SetParam("apt", kVp8Codec.id); 1143 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1144 1145 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0); 1146 rtx_codec2.SetParam("apt", rtx_codec.id); 1147 codecs.push_back(rtx_codec2); 1148 1149 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX " 1150 "as associated payload type " 1151 "should be rejected."; 1152 } 1153 1154 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) { 1155 std::vector<cricket::VideoCodec> codecs; 1156 codecs.push_back(kVp8Codec); 1157 codecs[0].id = 99; 1158 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1159 } 1160 1161 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRecvCodecsAcceptDefaultCodecs) { 1162 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); 1163 // (I've added this one.) Make sure they propagate down to VideoReceiveStream! 1164 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1165 } 1166 1167 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { 1168 std::vector<VideoCodec> codecs; 1169 codecs.push_back(kVp8Codec); 1170 codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0)); 1171 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); 1172 } 1173 1174 // TODO(pbos): Enable VP9 through external codec support 1175 TEST_F(WebRtcVideoChannel2Test, 1176 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) { 1177 std::vector<VideoCodec> codecs; 1178 codecs.push_back(kVp8Codec); 1179 codecs.push_back(kVp9Codec); 1180 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1181 } 1182 1183 TEST_F(WebRtcVideoChannel2Test, 1184 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) { 1185 std::vector<VideoCodec> codecs; 1186 codecs.push_back(kVp8Codec); 1187 codecs.push_back(kVp9Codec); 1188 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1189 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs. 1190 } 1191 1192 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) { 1193 std::vector<VideoCodec> codecs; 1194 codecs.push_back(kVp8Codec); 1195 codecs.push_back(kRedCodec); 1196 codecs[1].id = codecs[0].id; 1197 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); 1198 } 1199 1200 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) { 1201 std::vector<VideoCodec> codecs; 1202 codecs.push_back(kVp8Codec); 1203 codecs.push_back(kVp9Codec); 1204 codecs[1].id = codecs[0].id; 1205 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); 1206 } 1207 1208 TEST_F(WebRtcVideoChannel2Test, 1209 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) { 1210 std::vector<VideoCodec> codecs; 1211 codecs.push_back(kVp8Codec); 1212 codecs.push_back(kVp8Codec); 1213 codecs[1].id += 1; 1214 EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); 1215 } 1216 1217 TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) { 1218 EXPECT_FALSE(AddSendStream()->IsSending()); 1219 } 1220 1221 TEST_F(WebRtcVideoChannel2Test, DISABLED_ReceiveStreamReceivingByDefault) { 1222 // Is this test correct though? Auto-receive? Enable receive on first packet? 1223 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1224 } 1225 1226 TEST_F(WebRtcVideoChannel2Test, SetSend) { 1227 AddSendStream(); 1228 EXPECT_FALSE(channel_->SetSend(true)) 1229 << "Channel should not start without codecs."; 1230 EXPECT_TRUE(channel_->SetSend(false)) 1231 << "Channel should be stoppable even without set codecs."; 1232 1233 std::vector<cricket::VideoCodec> codecs; 1234 codecs.push_back(kVp8Codec); 1235 channel_->SetSendCodecs(codecs); 1236 std::vector<FakeVideoSendStream*> streams = GetFakeSendStreams(); 1237 ASSERT_EQ(1u, streams.size()); 1238 FakeVideoSendStream* stream = streams.back(); 1239 1240 EXPECT_FALSE(stream->IsSending()); 1241 1242 // false->true 1243 EXPECT_TRUE(channel_->SetSend(true)); 1244 EXPECT_TRUE(stream->IsSending()); 1245 // true->true 1246 EXPECT_TRUE(channel_->SetSend(true)); 1247 EXPECT_TRUE(stream->IsSending()); 1248 // true->false 1249 EXPECT_TRUE(channel_->SetSend(false)); 1250 EXPECT_FALSE(stream->IsSending()); 1251 // false->false 1252 EXPECT_TRUE(channel_->SetSend(false)); 1253 EXPECT_FALSE(stream->IsSending()); 1254 1255 EXPECT_TRUE(channel_->SetSend(true)); 1256 FakeVideoSendStream* new_stream = AddSendStream(); 1257 EXPECT_TRUE(new_stream->IsSending()) 1258 << "Send stream created after SetSend(true) not sending initially."; 1259 } 1260 1261 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveVp8Vga) { 1262 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1263 } 1264 1265 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveVp8Qvga) { 1266 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1267 } 1268 1269 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveH264SvcQqvga) { 1270 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1271 } 1272 1273 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendManyResizeOnce) { 1274 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1275 } 1276 1277 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) { 1278 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1279 } 1280 1281 TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetDscpOptions) { 1282 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1283 } 1284 1285 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithMaxBitrate) { 1286 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1287 } 1288 1289 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithLoweredBitrate) { 1290 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1291 } 1292 1293 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsSucceedsWhenSending) { 1294 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1295 } 1296 1297 TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetCodecOnScreencast) { 1298 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1299 } 1300 1301 TEST_F(WebRtcVideoChannel2Test, DISABLED_DontResetCodecOnSendFrame) { 1302 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1303 } 1304 1305 TEST_F(WebRtcVideoChannel2Test, 1306 DISABLED_DontRegisterDecoderIfFactoryIsNotGiven) { 1307 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1308 } 1309 1310 TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterDecoderIfFactoryIsGiven) { 1311 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1312 } 1313 1314 TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderMultipleTimes) { 1315 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1316 } 1317 1318 TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderForNonVP8) { 1319 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1320 } 1321 1322 TEST_F(WebRtcVideoChannel2Test, 1323 DISABLED_DontRegisterEncoderIfFactoryIsNotGiven) { 1324 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1325 } 1326 1327 TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterEncoderIfFactoryIsGiven) { 1328 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1329 } 1330 1331 TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterEncoderMultipleTimes) { 1332 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1333 } 1334 1335 TEST_F(WebRtcVideoChannel2Test, 1336 DISABLED_RegisterEncoderWithMultipleSendStreams) { 1337 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1338 } 1339 1340 TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterEncoderForNonVP8) { 1341 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1342 } 1343 1344 TEST_F(WebRtcVideoChannel2Test, DISABLED_FeedbackParamsForNonVP8) { 1345 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1346 } 1347 1348 TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecAddedToTheEnd) { 1349 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1350 } 1351 1352 TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecIgnored) { 1353 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1354 } 1355 1356 TEST_F(WebRtcVideoChannel2Test, DISABLED_UpdateEncoderCodecsAfterSetFactory) { 1357 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1358 } 1359 1360 TEST_F(WebRtcVideoChannel2Test, DISABLED_OnReadyToSend) { 1361 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1362 } 1363 1364 TEST_F(WebRtcVideoChannel2Test, DISABLED_CaptureFrameTimestampToNtpTimestamp) { 1365 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1366 } 1367 } // namespace cricket 1368